puppetserver and LDAP terminus

282 views
Skip to first unread message

Steve Huston

unread,
Feb 2, 2015, 5:52:13 PM2/2/15
to puppet...@googlegroups.com
I'm in the process of testing the upgrade of our puppet 3.7.4 instance
running under Apache/passenger to a new puppetserver setup on a RHEL7
machine. So far things have gone well, but the server is unable to do
LDAP lookups.

After spinning my wheels for quite some time wondering why I kept
getting told in the trace-level logging "Failed to load library 'ldap'
for feature 'ldap'" and discovering the whole new jruby-gems directory
that is different from the system one, I tried the "approved" method:

# puppetserver gem install ruby-ldap
Fetching: ruby-ldap-0.9.16.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing ruby-ldap:
ERROR: Failed to build gem native extension.

java -jar /usr/share/puppetserver/puppet-server-release.jar extconf.rb
Exception in thread "main" java.lang.IllegalStateException: Unable to
find bootstrap.cfg file via --bootstrap-config command line argument,
current working directory, or on classpath
at puppetlabs.trapperkeeper.bootstrap$find_bootstrap_config.invoke(bootstrap.clj:141)
at puppetlabs.trapperkeeper.core$boot_with_cli_data.invoke(core.clj:113)
at puppetlabs.trapperkeeper.core$run.invoke(core.clj:144)
at puppetlabs.trapperkeeper.core$main.doInvoke(core.clj:159)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:617)
at puppetlabs.trapperkeeper.main$_main.doInvoke(main.clj:7)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at puppetlabs.trapperkeeper.main.main(Unknown Source)


Gem files will remain installed in
/var/lib/puppet/jruby-gems/gems/ruby-ldap-0.9.16 for inspection.
Results logged to
/var/lib/puppet/jruby-gems/gems/ruby-ldap-0.9.16/./gem_make.out



--
Steve Huston - W2SRH - Unix Sysadmin, PICSciE/CSES & Astrophysical Sci
Princeton University | ICBM Address: 40.346344 -74.652242
345 Lewis Library |"On my ship, the Rocinante, wheeling through
Princeton, NJ 08544 | the galaxies; headed for the heart of Cygnus,
(267) 793-0852 | headlong into mystery." -Rush, 'Cygnus X-1'

Steve Huston

unread,
Feb 3, 2015, 5:40:50 PM2/3/15
to puppet...@googlegroups.com
So, I've spent another day beating on this problem and finally
achieved success. We started with:

> # puppetserver gem install ruby-ldap

Nobody pointed out, either here or in the documentation, that when
using puppetserver you have to use "jruby-ldap" instead. Once I did
that, the gem installed, yay! But it still didn't work. When the
server attempted to do a lookup it would still report that the search
failed, even though tcpdump showed it asking for the CN and getting
the right answer.

After quite a bit of prodding and help from a colleague I found that
jruby-ldap does not have a to_hash method in LDAP::Entry. This was
confirmed by a bit of code and comment at the top of
https://github.com/alibby/ldap_authenticated/blob/master/lib/ldap_authenticated.rb

I inserted that code into the ruby module, since I would have to
manually upgrade that but the puppetserver RPM might get upgraded (and
wipe out that change), and got a little further. Now, however, it
failed with another error: "Puppet Cannot reassign variable macaddress
on node syrinx.astro.princeton.edu"

On our old server running under passenger, if I look at
/var/lib/puppet/yaml/node/syrinx.astro.princeton.edu I see there's
both a "macaddress" and a "macAddress", so I realized what's going on
- the downcase in that code snippet is causing two facts to appear at
once.

All in all, this tells me a few things:

1) The documentation for using LDAP with the new puppetserver needs to
be updated to reflect not only that one must use 'jruby-ldap' (and
puppetserver gem install at that) but that the tests listed (running
ruby -rpuppet -e 'p Puppet.features.ldap?' and such) are incorrect as
they will report 'true' if you have the gem installed through the
normal system commands but puppetserver will not see it.

2) There needs to be a patch, perhaps somewhere in puppetserver, that
makes sure the jruby-ldap LDAP::Entry class has a 'to_hash' method (or
code around the necessity of needing it), for example:

if RUBY_PLATFORM =~ /^java.*/i
class LDAP::Entry
def to_hash
h = {}
get_attributes.each { |a| h[a.to_sym] = self[a] }
h[:dn] = [dn]
h
end
end
end

3) I discovered when I spun up my VM this morning that puppetserver
failed to start because it wanted to create a /var/run/puppet (which
it does not appear to actually use thereafter). Since /var/run is on
a tmpfs on RHEL7, and owned by root, yet the puppetserver process runs
as user 'puppet', this will fail on every reboot. Admittedly I'm not
running the puppetlabs RPM, but our package maintainer does a very
good job of making sure that the scripts and setups are duplicated if
he rebuilds something - please correct me if the logic to recreate
this directory is included somewhere and I can point it out to him to
fix in our repository.

Eric Sorenson

unread,
Jun 9, 2015, 5:43:35 PM6/9/15
to puppet...@googlegroups.com, hus...@astro.princeton.edu
Hi Steve, thanks for tracking this down! The LDAP node terminus is a useful but pretty cobwebby corner of Puppet (IIRC it predates the existence of the External Node Classifier API which is what most sites are using now). So as you found its docs do not get a lot of love and there are no acceptance/CI tests that cover its use.

I have a couple of comments inline. Our education team ran across this issue, which is why I'm replying to a months-old thread. We're tracking it in JIRA at https://tickets.puppetlabs.com/browse/SERVER-711


On Tuesday, February 3, 2015 at 2:40:50 PM UTC-8, Steve Huston wrote:
So, I've spent another day beating on this problem and finally
achieved success.  We started with:

> # puppetserver gem install ruby-ldap

Nobody pointed out, either here or in the documentation, that when
using puppetserver you have to use "jruby-ldap" instead.  Once I did
that, the gem installed, yay!  But it still didn't work.  When the
server attempted to do a lookup it would still report that the search
failed, even though tcpdump showed it asking for the CN and getting
the right answer.

After quite a bit of prodding and help from a colleague I found that
jruby-ldap does not have a to_hash method in LDAP::Entry.  This was
confirmed by a bit of code and comment at the top of
https://github.com/alibby/ldap_authenticated/blob/master/lib/ldap_authenticated.rb

I inserted that code into the ruby module, since I would have to
manually upgrade that but the puppetserver RPM might get upgraded (and
wipe out that change), and got a little further.  Now, however, it
failed with another error: "Puppet Cannot reassign variable macaddress
on node syrinx.astro.princeton.edu"

It seems like the to_hash change would be better off as a patch to the upstream module vs a monkey-patch in Puppet. 
 

On our old server running under passenger, if I look at
/var/lib/puppet/yaml/node/syrinx.astro.princeton.edu I see there's
both a "macaddress" and a "macAddress", so I realized what's going on
- the downcase in that code snippet is causing two facts to appear at
once.

That's not great either :( 

All in all, this tells me a few things:

1) The documentation for using LDAP with the new puppetserver needs to
be updated to reflect not only that one must use 'jruby-ldap' (and
puppetserver gem install at that) but that the tests listed (running
ruby -rpuppet -e 'p Puppet.features.ldap?' and such) are incorrect as
they will report 'true' if you have the gem installed through the
normal system commands but puppetserver will not see it.

That's true. Would you be willing to work up a pull request against the puppet-docs repo with the things you've learned? The source markdown for the guide is here:

 

2) There needs to be a patch, perhaps somewhere in puppetserver, that
makes sure the jruby-ldap LDAP::Entry class has a 'to_hash' method (or
code around the necessity of needing it), for example:

if RUBY_PLATFORM =~ /^java.*/i
  class LDAP::Entry
     def to_hash
        h = {}
        get_attributes.each { |a| h[a.to_sym] = self[a] }
        h[:dn] = [dn]
        h
     end
  end
end

As I said, I think this would be better as an upstream patch to the jruby-ldap project, especially since you found another project that had to do the same thing.  Carrying individual monkey-patches against upstream projects is a practice that rarely ends well in my experience.

 
3) I discovered when I spun up my VM this morning that puppetserver
failed to start because it wanted to create a /var/run/puppet (which
it does not appear to actually use thereafter).  Since /var/run is on
a tmpfs on RHEL7, and owned by root, yet the puppetserver process runs
as user 'puppet', this will fail on every reboot.  Admittedly I'm not
running the puppetlabs RPM, but our package maintainer does a very
good job of making sure that the scripts and setups are duplicated if
he rebuilds something - please correct me if the logic to recreate
this directory is included somewhere and I can point it out to him to
fix in our repository.


This one is fixed in Puppet Server 1.0.8 and 2.1.0: https://tickets.puppetlabs.com/browse/SERVER-336

--eric0

Steve Huston

unread,
Mar 29, 2017, 12:05:19 PM3/29/17
to puppet...@googlegroups.com
So big surprise to me when I'm looking to move our infrastructure from
openldap to freeipa, and having trouble getting puppetserver to talk
to it, when I find there was a reply to my posts that I'd missed. And
sadly, there was no resolution then either.

Yes, jruby-ldap updating their code would be great, but they haven't
had any updates since 2012. And this problem still exists. And I've
found a new wrinkle - the same documentation that talks about using
the LDAP terminus also mentions using SSL or TLS, but trying to use
TLS fails with an error that there's too many arguments passed to the
open command ("Puppet Could not connect to LDAP: Could not connect to
LDAP: wrong number of arguments calling `initialize` (3 for 2)").

When I also found the ticket you referenced in this message, I saw
some comments about how this is a "dusty corner" of puppet. That's
great, but either the problem needs to be fixed, or the whole of it
needs to stop being referenced as possible and supported when it is
obviously not. If the former, I would imagine removing reliance on
jruby-ldap which is already shown to be broken is the way to go, and
if the latter is the case I will have to make my own modifications to
jruby-ldap to make it work, once I figure out what those modifications
should be.
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to puppet-users...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-users/f2cb5d50-7ea5-45a0-9e5e-c117eda82fe3%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Peter Souter

unread,
Jun 15, 2017, 10:11:11 AM6/15/17
to Puppet Users
Hi Steve,

I've actually been working with someone who was using the LDAP 
terminus and had the same issue. In the end I took the patch 
you posted in this thread and added it to a fork of the gem so it can be
just installed from Rubygems:


That worked for them, but they weren't using certs.

If you can figure out the ssl issue, I can add a patch for that. From a quick
glane, I think adding an options hash to the initalisation method in jruby-ldap
would be the way forward, but I don't have the testing rig for SSL'd ldap 
or the ldap knowledge to really moved forward. 

If you're still using it, we can probably put a patch in to fix it, but most people
have moved to either the node classifier in PE or something like hiera-ldap, 
and using a hiera_include model from that (also assisted customer with that in the
past)
Reply all
Reply to author
Forward
0 new messages