Ampelofilosofies

homeaboutrss
The mind is like a parachute. If it doesn't open, you're meat.

Workaround for Jenkins CLI authentication

30 May 2016

Been trying to get Jenkins to do various nifty things automatically and it turns out it is possible, only the new 2.x series has authentication turned on by default and we somehow need to authenticate jenkins-cli to be able to do anything.

This creates a chicken-or-egg problem, since we need jenkins-cli to create the credentials that will enable jenkins-cli to login in the first place. At least if we use the jenkins cookbook or until Jnekins gets a proper HTTP API for these things.

And as of some recent version before 2.x jenkins-cli will not allow the use of passwords anymore. Sometimes I think people go out of their way to make automating things difficult.

I chewed at the problem for several days and lots of different angles. At the moment the easiest solution seems to be to disable security for the duration of the setup. Fortunately with a bit of Nokogiri magic this is not a difficult problem.

How to turn off security

Find the Jenkins config.xml, set the value of useSecurity to false.

Contrary to the Jenkins wiki advice, you don’t really have to remove the authorizationStrategy and securityRealm elements. Leaving them be actually makes restoring the original state easier.

You can save the following to a file (let’s say security.rb) and drop it in the libraries/ directory of your cookbook.

require "nokogiri"

def jenkins_security state,jenkins_home
  jenkins_config_file=File.join(jenkins_home,"config.xml")
  raise "Could not find the Jenkins configuration file at #{jenkins_home}. The disable_security recipe needs to run *after* the jenkins-master default recipe." unless File.exist?(jenkins_config_file)
  jenkins_config = Nokogiri::XML(File.open(jenkins_config_file))
  security_settings=jenkins_config.xpath("//hudson//useSecurity")
  case state
  when :on
    security_settings.first.content="true"
  when :off
    security_settings.first.content="false"
  else
    raise "Only :on and :off are valid state values"
  end

  File.open(jenkins_config_file,"w")  do |f|
    f.write(jenkins_config.to_xml)
  end
end

The recipe that uses the above code is

chef_gem 'nokogiri'

ruby_block 'disable_security' do
  block do
    jenkins_security :off,node['jenkins']['master']['home']
  end
  notifies :restart, 'service[jenkins]', :immediately
  action :run
end

The nice thing about this approach is that once we’re done with Jenkins we can reactivate security (just replace the :off with :on in the recipe code) and we’re back to the initial state.

Pitfalls

You will need to block and wait for Jenkins to boot up before including this. For a way to do this you can check cookbooks-jenkins-simple-app