From f6e10c1db16267ec433445e74bc9a03f6bb3dd7e Mon Sep 17 00:00:00 2001
From: Guilhem Moulin <guilhem@fripost.org>
Date: Thu, 11 Jun 2015 10:49:36 +0200
Subject: Use a single LDAP connection per Munin round to collect slapd
 statistics.

Using multigraphs instead.
---
 roles/common-LDAP/tasks/main.yml                   |  21 +-
 .../files/usr/local/share/munin/plugins/slapd2     | 269 ++++++++++++++++
 .../files/usr/local/share/munin/plugins/slapd2_    | 348 ---------------------
 .../etc/munin/plugin-conf.d/munin-node.j2          |   3 +-
 4 files changed, 276 insertions(+), 365 deletions(-)
 create mode 100755 roles/common/files/usr/local/share/munin/plugins/slapd2
 delete mode 100755 roles/common/files/usr/local/share/munin/plugins/slapd2_

diff --git a/roles/common-LDAP/tasks/main.yml b/roles/common-LDAP/tasks/main.yml
index a8c784d..aff0e58 100644
--- a/roles/common-LDAP/tasks/main.yml
+++ b/roles/common-LDAP/tasks/main.yml
@@ -8,7 +8,7 @@
     - ldapvi
     - db-util
     - python-ldap
-    # for the 'slapd2_' munin plugin
+    # for the 'slapd2' munin plugin
     - libnet-ldap-perl
     - libauthen-sasl-perl
 
@@ -137,22 +137,13 @@
         mode=0755
 
 
-- name: Install 'slapd2_' Munin wildcard plugin
-  # we don't install 'slapd_' because it doesn't support SASL binds
-  file: src=/usr/local/share/munin/plugins/slapd2_
-        dest=/etc/munin/plugins/slapd2_{{ item }}
+- name: Install 'slapd2' Munin plugin
+  # we don't install 'slapd_' because it doesn't support SASL binds and
+  # ours is more parcimonious with LDAP connections
+  file: src=/usr/local/share/munin/plugins/slapd2
+        dest=/etc/munin/plugins/slapd2
         owner=root group=root
         state=link force=yes
-  with_items:
-    # sudo /usr/share/munin/plugins/slapd2_ suggest
-    - connections
-    - statistics_entries
-    - operations_diff
-    - statistics_referrals
-    - statistics_pdu
-    - waiters
-    - statistics_bytes
-    - operations
   tags:
     - munin
     - munin-node
diff --git a/roles/common/files/usr/local/share/munin/plugins/slapd2 b/roles/common/files/usr/local/share/munin/plugins/slapd2
new file mode 100755
index 0000000..68c482b
--- /dev/null
+++ b/roles/common/files/usr/local/share/munin/plugins/slapd2
@@ -0,0 +1,269 @@
+#!/usr/bin/perl -w
+
+# Munin plugin for monitoring slapd.  Based on Bjorn Ruberg's slapd_
+# plugin.  The main difference is that in our case munin SASL-binds
+# against the LDAP directory, and a single connection is used to collect
+# all statistics.
+# Copyright Bjorn Ruberg <bjorn@ruberg.no>
+# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use warnings;
+use strict;
+
+use Net::LDAP ();
+use Net::LDAP::Util ();
+use Authen::SASL ();
+
+# The possible measurements
+my %OPS =
+    ('statistics_bytes'
+     => {
+         'search' => "cn=Bytes,cn=Statistics",
+         'desc'   => "The number of bytes sent by the LDAP server.",
+         'vlabel' => 'Bytes per ${graph_period}',
+         'label'  => 'Bytes',
+         'title'  => "Number of bytes sent",
+         'info'   => "The graph shows the number of bytes sent",
+	 'scope'  => "base"
+         },
+     'statistics_pdu'
+     => {
+         'search' => "cn=PDU,cn=Statistics",
+         'desc'   => "The number of PDUs sent by the LDAP server.",
+         'vlabel' => 'PDUs per ${graph_period}',
+         'label'  => 'PDUs',
+         'title'  => "Number of PDUs sent",
+         'info'   => "The graph shows the number of PDUs sent",
+	 'scope'  => "base"
+         },
+     # Referrals
+     'statistics_referrals' 
+     => {
+         'search' => "cn=Referrals,cn=Statistics",
+         'desc'   => "The number of Referrals sent by the LDAP server.",
+         'vlabel' => 'Referrals per ${graph_period}',
+         'label'  => 'Referrals',
+         'title'  => "Number of LDAP Referrals",
+         'info'   => "The graph shows the number of referrals sent",
+	 'scope'  => "base"
+         },
+     # Entries
+     'statistics_entries'
+     => {
+         'search' => "cn=Entries,cn=Statistics",
+         'desc'   => "The number of Entries sent by the LDAP server.",
+         'vlabel' => 'Entries per ${graph_period}',
+         'label'  => 'Entries',
+         'title'  => "Number of LDAP Entries",
+         'info'   => "The graph shows the number of entries sent",
+	 'scope'  => "base"
+         },
+     # Only read Total
+     'connections' 
+     => {
+         'search' => 'cn=Total,cn=Connections',
+         'desc'   => 'The number of connections',
+         'label'  => 'Connections',
+         'vlabel' => 'Connections per ${graph_period}',
+         'title'  => 'Number of Connections',
+         'info'   => 'Number of connections to the LDAP server',
+         'scope'  => "base"
+         },
+     # dn: cn=Write,cn=Waiters,cn=Monitor
+     # dn: cn=Read,cn=Waiters,cn=Monitor
+     'waiters' 
+     => {
+         'search' => 'cn=Waiters',
+         'filter' => '(|(cn=Write)(cn=Read))',
+         'desc'   => "The current number of Waiters",
+         'label2' => {'write' => 'Write',
+                      'read'  => 'Read'},
+         'vlabel' => "Waiters",
+         'title'  => "Number of Waiters",
+         'info'   => "The graph shows the number of Waiters"
+         },
+     'operations'
+     => {
+         'search' => "cn=Operations",
+         'desc'   => "Operations",
+         'vlabel' => 'Operations per ${graph_period}',
+         'label'  => 'Operations',
+         'title'  => "Operations",
+         'info'   => "Number of completed LDAP operations"
+         },
+     'operations_diff'
+     => {
+         'search' => "cn=Operations",
+         'desc'   => "Operations deviance",
+         'vlabel' => 'Deviance',
+         'label'  => 'Deviance',
+         'title'  => "Operations deviance",
+         'info'   => "Deviance between Initiated and Completed ops"
+       }
+     );
+
+
+my $ldap = Net::LDAP::->new( 'ldapi://' );
+my $sasl = Authen::SASL::->new( mechanism => 'EXTERNAL' );
+my $mesg = $ldap->bind( undef, sasl => $sasl );
+die "LDAP error code $mesg->code: $mesg->error\n",
+    Net::LDAP::Util::ldap_error_text($mesg), "\n"
+    if $mesg->code;
+my $basedn = 'cn=Monitor';
+
+
+if (@ARGV and $ARGV[0] eq 'config') {
+    foreach my $action (keys %OPS) {
+        print "multigraph slapd2_$action\n";
+        print "graph_title $OPS{$action}->{title}\n";
+        print "graph_info $OPS{$action}->{info}\n";
+        print "graph_vlabel $OPS{$action}->{vlabel}\n";
+        print "graph_args --base 1000 -l 0\n";
+        print "graph_scale no\n";
+        print "graph_category OpenLDAP\n";
+
+        if ($OPS{$action}->{label2}) {
+            foreach my $key (keys %{$OPS{$action}->{label2}}) {
+              my $name = $action . "_" . $key;
+              print "$name.label $OPS{$action}->{label2}->{$key}\n";
+              print "$name.type GAUGE\n";
+            }
+        } elsif ($action =~ /^operations(?:_diff)?$/) {
+            my $mesg = $ldap->search ( base   => "$OPS{$action}->{search},$basedn"
+                                     , scope  => 'one'
+                                     , deref  => 'never'
+                                     , filter => '(objectclass=*)'
+                                     , attrs  => [ 'monitorOpInitiated'
+                                                 , 'monitorOpCompleted'
+                                                 , 'cn' ]
+                                     );
+            die "LDAP error code $mesg->code: $mesg->error\n",
+                Net::LDAP::Util::ldap_error_text($mesg), "\n"
+                if $mesg->code;
+    
+            while (my $e = $mesg->pop_entry) {
+                my $cn = $e->get_value('cn');
+                my $name = $action .'_'. lc $cn;
+                print "$name.label $cn\n";
+                print "$name.type DERIVE\n";
+                print "$name.min 0\n";
+            
+                if ($action eq "operations") {
+                    print "$name.info The number of $cn operations\n";
+                } else {
+                    print "$name.info The difference between Initiated ";
+                    print "and Completed operations (should be 0)\n";
+                    print "$name.warning 1\n";
+                }            
+            }
+        } else {
+            print "$action.label $OPS{$action}->{label}\n";
+            print "$action.type DERIVE\n";
+            print "$action.min 0\n";
+        }
+    }
+}
+
+else {
+    foreach my $action (keys %OPS) {
+        my $searchdn = "$OPS{$action}->{search},$basedn";
+        my @searchattrs;
+
+        if ($action =~ /^operations(_diff)?$/) {
+            # We look for different parameters in Operations branch
+            @searchattrs = ('monitorOpInitiated', 'monitorOpCompleted', 'cn');
+        } else {
+            @searchattrs = ('monitorCounter', 'cn');
+        }
+
+        my $mesg = $ldap->search ( base   => "$OPS{$action}->{search},$basedn"
+                                 , scope  => $OPS{$action}->{scope} // 'one'
+                                 , deref  => 'never'
+                                 , filter => $OPS{$action}->{filter} // '(objectclass=*)'
+                                 , attrs  => \@searchattrs
+                                 );
+        die "LDAP error code $mesg->code: $mesg->error\n",
+            Net::LDAP::Util::ldap_error_text($mesg), "\n"
+            if $mesg->code;
+    
+        print "multigraph slapd2_$action\n";
+        while (my $e = $mesg->pop_entry) {
+            my $cn = $e->get_value('cn');
+            if ($action =~ /operations(_diff)?$/) {
+        	    if ($1) {
+        	        my $opsInit = $e->get_value('monitorOpInitiated'); 
+        	        my $opsComp = $e->get_value('monitorOpCompleted');
+        	        printf "operations_diff_%s.value %d\n", lc $cn, ($opsInit - $opsComp);
+        	} else {
+        	    printf "operations_%s.value %d\n", lc $cn, $e->get_value('monitorOpCompleted');
+        	}
+            } else {
+        	    # Hotfix, must do for now
+                printf "%s.value %d\n",
+                    (($action =~ /_/ or $action eq 'connections') ? lc $action : lc "${action}_${cn}"),
+                    $e->get_value('monitorCounter');
+            }
+        }
+    }
+}
+
+#$mesg = $ldap->search( base   => 'cn=Monitor'
+#                     , scope  => 'base'
+#                     , deref  => 'never'
+#                     , attrs  => 
+
+$ldap->unbind();
+
+
+#$mesg =
+#    $ldap->search (
+#                   base   => $searchdn,
+#                   scope  => $scope,
+#                   filter => $filter,
+#                   attrs  => $searchattrs,
+#                   );
+#
+#$mesg->code && die $mesg->error;
+#
+#my $max = $mesg->count;
+#
+#for (my $i = 0 ; $i < $max ; $i++) {
+#    my $entry = $mesg->entry ($i);
+#    my $cn = $entry->get_value('cn');
+#    if ($action =~ /operations(_diff)?$/) {
+#	if ($1) {
+#	    my $opsInit =
+#		$entry->get_value('monitorOpInitiated'); 
+#	    my $opsComp =
+#		$entry->get_value('monitorOpCompleted');
+#	    print lc ("operations_diff_${cn}.value ");
+#	    print ($opsInit - $opsComp);
+#	    print "\n";
+#	} else {
+#	    print lc ("operations_${cn}.value ");
+#	    print $entry->get_value('monitorOpCompleted'),
+#	    "\n";
+#	}
+#    } else {
+#	# Hotfix, must do for now
+#	if ($action =~ /_/ || $action eq 'connections') {
+#	    print lc ("${action}.value ");
+#	} else {
+#	    print lc ("${action}_${cn}.value ");
+#	}
+#	print $entry->get_value('monitorCounter'), "\n";
+#    }
+#}
+#$ldap->unbind;
diff --git a/roles/common/files/usr/local/share/munin/plugins/slapd2_ b/roles/common/files/usr/local/share/munin/plugins/slapd2_
deleted file mode 100755
index 56774ac..0000000
--- a/roles/common/files/usr/local/share/munin/plugins/slapd2_
+++ /dev/null
@@ -1,348 +0,0 @@
-#!/usr/bin/perl -w
-# -*- perl -*-
-# vim: ft=perl
-
-# Copyright Bjorn Ruberg <bjorn@ruberg.no>
-# Licenced under GPL v2
-#
-# TODO:
-# - Check for OpenLDAP version
-
-# We use one script for all monitoring.
-# This script may be symlinked with several names, all
-# performing different functions:
-# slapd_statistics_bytes
-# slapd_statistics_pdu
-# slapd_statistics_referrals
-# slapd_statistics_entries
-# slapd_connections
-# slapd_waiters
-# slapd_operations
-# slapd_operations_diff
-
-# Magic markers
-#%# family=auto
-#%# capabilities=autoconf suggest
-
-use strict;
-
-my $ret = '';
-
-if (! eval "require Net::LDAP;") {
-   $ret = "Net::LDAP not found";
-}
-
-use vars qw ( $config $param $act $scope $descr $cn $vlabel
-	      $info $title $label);
-
-# Change these to reflect your LDAP ACL. The given DN must have
-# read access to the Monitor branch.
-my $basedn = "cn=Monitor";
-my $server = ($ENV{'server'} || 'localhost');
-my $userdn = ($ENV{'binddn'} || '');
-my $userpw = ($ENV{'bindpw'} || '');
-
-# Remember: connections, bytes, pdu needs scope=base
-
-# The possible measurements
-my %ops =
-    ('statistics_bytes'
-     => {
-         'search' => "cn=Bytes,cn=Statistics",
-         'desc'   => "The number of bytes sent by the LDAP server.",
-         'vlabel' => 'Bytes per ${graph_period}',
-         'label'  => 'Bytes',
-         'title'  => "Number of bytes sent",
-         'info'   => "The graph shows the number of bytes sent",
-	 'scope'  => "base"
-         },
-     'statistics_pdu'
-     => {
-         'search' => "cn=PDU,cn=Statistics",
-         'desc'   => "The number of PDUs sent by the LDAP server.",
-         'vlabel' => 'PDUs per ${graph_period}',
-         'label'  => 'PDUs',
-         'title'  => "Number of PDUs sent",
-         'info'   => "The graph shows the number of PDUs sent",
-	 'scope'  => "base"
-         },
-     # Referrals
-     'statistics_referrals' 
-     => {
-         'search' => "cn=Referrals,cn=Statistics",
-         'desc'   => "The number of Referrals sent by the LDAP server.",
-         'vlabel' => 'Referrals per ${graph_period}',
-         'label'  => 'Referrals',
-         'title'  => "Number of LDAP Referrals",
-         'info'   => "The graph shows the number of referrals sent",
-	 'scope'  => "base"
-         },
-     # Entries
-     'statistics_entries'
-     => {
-         'search' => "cn=Entries,cn=Statistics",
-         'desc'   => "The number of Entries sent by the LDAP server.",
-         'vlabel' => 'Entries per ${graph_period}',
-         'label'  => 'Entries',
-         'title'  => "Number of LDAP Entries",
-         'info'   => "The graph shows the number of entries sent",
-	 'scope'  => "base"
-         },
-     # Only read Total
-     'connections' 
-     => {
-         'search' => 'cn=Total,cn=Connections',
-         'desc'   => 'The number of connections',
-         'label'  => 'Connections',
-         'vlabel' => 'Connections per ${graph_period}',
-         'title'  => 'Number of Connections',
-         'info'   => 'Number of connections to the LDAP server',
-         'scope'  => "base"
-         },
-     # dn: cn=Write,cn=Waiters,cn=Monitor
-     # dn: cn=Read,cn=Waiters,cn=Monitor
-     'waiters' 
-     => {
-         'search' => 'cn=Waiters',
-         'filter' => '(|(cn=Write)(cn=Read))',
-         'desc'   => "The current number of Waiters",
-         'label2' => {'write' => 'Write',
-                      'read'  => 'Read'},
-         'vlabel' => "Waiters",
-         'title'  => "Number of Waiters",
-         'info'   => "The graph shows the number of Waiters"
-         },
-     'operations'
-     => {
-         'search' => "cn=Operations",
-         'desc'   => "Operations",
-         'vlabel' => 'Operations per ${graph_period}',
-         'label'  => 'Operations',
-         'title'  => "Operations",
-         'info'   => "Number of completed LDAP operations"
-         },
-     'operations_diff'
-     => {
-         'search' => "cn=Operations",
-         'desc'   => "Operations deviance",
-         'vlabel' => 'Deviance',
-         'label'  => 'Deviance',
-         'title'  => "Operations deviance",
-         'info'   => "Deviance between Initiated and Completed ops"
-       }
-     );
-
-# Config subroutine
-sub config {
-    my $action = shift;
-    print <<EOF;
-graph_args --base 1000 -l 0
-graph_scale no
-graph_vlabel $ops{$action}->{'vlabel'}
-graph_title $ops{$action}->{'title'}
-graph_category OpenLDAP
-graph_info $ops{$action}->{'info'}
-EOF
-    
-    if ($ops{$action}->{'label2'}) {
-        while (my ($key, $val) = each (%{$ops{$action}->{'label2'}})) {
-          my $name = $action . "_" . $key;
-          print "$name.label $val\n";
-          print "$name.type GAUGE\n";
-        }
-    } elsif ($action =~ /^operations(?:_diff)?$/) {
-        my $ldap = Net::LDAP->new ($server)
-            or die "Failed to connect to server $server: $@";
-        my $mesg;
-        if ($userdn ne '') {
-          $mesg = $ldap->bind ($userdn, password => $userpw)
-              or die "Failed to bind with $userdn: $@";
-        } else {
-          require Authen::SASL;
-          my $sasl = Authen::SASL::->new( mechanism => 'EXTERNAL' );
-          $mesg = $ldap->bind( undef, sasl => $sasl )
-              or die "Failed to SASL bind: $@";
-        }
-        if ($mesg->code) {
-          die "Failed to bind: " . $mesg->error;
-        }
-        my $searchdn = $ops{$action}->{'search'} . "," . $basedn;
-        $mesg =
-            $ldap->search (
-                           base   => $searchdn,
-                           scope  => 'one',
-                           filter => '(objectclass=*)',
-                           attrs  => ['monitorOpInitiated',
-                                      'monitorOpCompleted',
-                                      'cn'],
-                           );
-        $mesg->code && die $mesg->error;
-        
-        my $max = $mesg->count;
-        for (my $i = 0 ; $i < $max ; $i++) {
-            my $entry = $mesg->entry ($i);
-            my $cn = $entry->get_value ('cn');
-            my $name = $action . "_" . lc ($cn);
-            print "$name.label $cn\n";
-            print "$name.type DERIVE\n";
-            print "$name.min 0\n";
-            if ($action eq "operations") {
-                print "$name.info The number of $cn operations\n";
-            } else {
-                print "$name.info The difference between Initiated ";
-                print "and Completed operations (should be 0)\n";
-                print "$name.warning 1\n";
-            }            
-        }
-
-        $ldap->unbind;
-    } else {
-        print "$action.label $ops{$action}->{'label'}\n";
-        print "$action.type DERIVE\n";
-        print "$action.min 0\n";
-    }
-}
-
-# Determine action based on filename first
-(my $action = $0) =~ s/^.*slapd2_([\w\d_]+)$/$1/;
-
-if ($ARGV[0]) {
-    if ($ARGV[0] eq 'autoconf') {
-        # Check for Net::LDAP
-	if ($ret) {
-	    print "no ($ret)\n";
-	    exit 0;
-	}
-
-        # Check for LDAP version 3
-        my $ldap = Net::LDAP->new ($server, version => 3)
-            or do { print "no ($@)\n"; exit 0; };
-
-        my $mesg;
-        if ($userdn ne '') {
-          $mesg = $ldap->bind ($userdn, password => $userpw)
-            or do { print "no ($@)\n"; exit 0; };
-        } else {
-          require Authen::SASL;
-          my $sasl = Authen::SASL::->new( mechanism => 'EXTERNAL' );
-          $mesg = $ldap->bind( undef, sasl => $sasl )
-            or do { print "no ($@)\n"; exit 0; };
-        }
-        if ($mesg->code) {
-          print "no (" . $mesg->error . ")\n";
-          exit 0;
-        }
-
-        $mesg =
-            $ldap->search (
-                           base   => $basedn,
-                           scope  => 'one',
-                           filter => '(objectClass=monitorServer)',
-                           attrs  => [
-                                       'cn',
-                                     ],
-                           );
-        if ($mesg->code) {
-          print "no (" . $mesg->error . ")\n";
-          exit 0;
-        }
-        print "yes\n";
-        exit 0;
-    } elsif ($ARGV[0] eq "config") {
-        if(!exists $ops{$action}) {
-            die "Unknown action specified: $action";
-        }
-        &config ($action);
-    } elsif ($ARGV[0] eq "suggest") {
-        print join ("\n", keys (%ops)), "\n";
-    }
-    exit 0;
-}
-
-# If $action isn't in %ops, we quit
-if(!exists $ops{$action}) {
-    die "Unknown action specified: $action";
-}
-
-# Default scope for LDAP searches. We'll change to other scopes if
-# necessary.
-$scope = "one";
-
-# Net::LDAP variant
-my $ldap = Net::LDAP->new ($server, version => 3)
-    or die "Failed to connect to server $server: $@";
-my $mesg;
-if ($userdn ne '') {
-  $mesg = $ldap->bind ($userdn, password => $userpw)
-      or die "Failed to bind with $userdn: $@";
-} else {
-  require Authen::SASL;
-  my $sasl = Authen::SASL::->new( mechanism => 'EXTERNAL' );
-  $mesg = $ldap->bind( undef, sasl => $sasl )
-      or die "Failed to bind anonymously: $@";
-}
-if ($mesg->code) {
-  die "Failed to bind: " . $mesg->error;
-}
-
-my $searchdn = $ops{$action}->{'search'} . "," . $basedn;
-my $searchattrs;
-
-if ($action =~ /^operations(_diff)?$/) {
-    # We look for different parameters in Operations branch
-    $searchattrs = ['monitorOpInitiated', 'monitorOpCompleted', 'cn'];
-} else {
-    $searchattrs = ['monitorCounter', 'cn'];
-}
-
-my $filter;
-if ($ops{$action}->{'filter'}) {
-  $filter = "(&(objectclass=*)" . $ops{$action}->{'filter'} . ")";
-} else {
-  $filter = "(objectClass=*)";
-}
-
-if ($ops{$action}->{'scope'}) {
-  $scope = $ops{$action}->{'scope'};
-}
-
-$mesg =
-    $ldap->search (
-                   base   => $searchdn,
-                   scope  => $scope,
-                   filter => $filter,
-                   attrs  => $searchattrs,
-                   );
-
-$mesg->code && die $mesg->error;
-
-my $max = $mesg->count;
-
-for (my $i = 0 ; $i < $max ; $i++) {
-    my $entry = $mesg->entry ($i);
-    my $cn = $entry->get_value('cn');
-    if ($action =~ /operations(_diff)?$/) {
-	if ($1) {
-	    my $opsInit =
-		$entry->get_value('monitorOpInitiated'); 
-	    my $opsComp =
-		$entry->get_value('monitorOpCompleted');
-	    print lc ("operations_diff_${cn}.value ");
-	    print ($opsInit - $opsComp);
-	    print "\n";
-	} else {
-	    print lc ("operations_${cn}.value ");
-	    print $entry->get_value('monitorOpCompleted'),
-	    "\n";
-	}
-    } else {
-	# Hotfix, must do for now
-	if ($action =~ /_/ || $action eq 'connections') {
-	    print lc ("${action}.value ");
-	} else {
-	    print lc ("${action}_${cn}.value ");
-	}
-	print $entry->get_value('monitorCounter'), "\n";
-    }
-}
-$ldap->unbind;
diff --git a/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2
index e5ba9b5..6cfa3f9 100644
--- a/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2
+++ b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2
@@ -136,7 +136,6 @@ env.PGPORT 5432
 [fail2ban]
 user root
 
-[slapd2_*]
+[slapd2]
 user munin
 group munin
-env.server ldapi://
-- 
cgit v1.2.3