Showing with 172 additions and 59 deletions.
  1. +22 −0 .travis.yml
  2. +32 −0 CHANGELOG.md
  3. +16 −0 Gemfile
  4. +1 −1 Modulefile
  5. +10 −7 README.md
  6. +2 −0 Rakefile
  7. +19 −9 lib/puppet/provider/java_ks/keytool.rb
  8. +16 −3 lib/puppet/type/java_ks.rb
  9. +36 −37 spec/unit/puppet/provider/java_ks/keytool_spec.rb
  10. +18 −2 spec/unit/puppet/type/java_ks_spec.rb
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
language: ruby
bundler_args: --without development
script: "bundle exec rake spec SPEC_OPTS='--format documentation'"
rvm:
- 1.8.7
- 1.9.3
- ruby-head
env:
- PUPPET_GEM_VERSION="~> 2.7.0"
- PUPPET_GEM_VERSION="~> 3.0.0"
- PUPPET_GEM_VERSION="~> 3.1.0"
matrix:
allow_failures:
- rvm: ruby-head
exclude:
- rvm: 1.9.3
env: PUPPET_GEM_VERSION="~> 2.7.0"
- rvm: ruby-head
env: PUPPET_GEM_VERSION="~> 2.7.0"
notifications:
email: false

32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## puppetlabs-java_ks changelog

Release notes for the puppetlabs-java_ks module

---------------------------------------

1.1.0
=====

This minor feature provides a number of new features:

* We have introduced a new property `password_file` to the java_ks type, so
that users can specify a plain text file to be used for unlocking a Java
keystore file.
* A new property `path` has been also added so you can add a custom search
path for the command line tooling (keystore etc.)

Travis-CI support has also been added to improve testing.

#### Detailed Changes

* Support for executables outside the system default path (Filip Hrbek)
* Add password_file to type (Raphaël Pinson)
* Travis ci support (Adrien Thebo)
* refactor keytool provider specs (Adrien Thebo)

---------------------------------------

0.0.6
=====

Fixes an issue with ibm java handling input from stdin on SLES
16 changes: 16 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
source "https://rubygems.org"

group :development, :test do
gem 'rake'
gem 'rspec', "~> 2.11.0", :require => false
gem 'mocha', "~> 0.10.5", :require => false
gem 'puppetlabs_spec_helper', :require => false
end

if puppetversion = ENV['PUPPET_GEM_VERSION']
gem 'puppet', puppetversion, :require => false
else
gem 'puppet', :require => false
end

# vim:ft=ruby
2 changes: 1 addition & 1 deletion Modulefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name 'puppetlabs-java_ks'
version '1.0.1'
version '1.1.0'

author 'puppetlabs'
license 'ASL 2.0'
Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
java_ks
=======

[![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-java_ks.png?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-java_ks)

####Table of Contents

1. [Overview - What is the java_ks module?](#overview)
Expand Down Expand Up @@ -91,6 +93,14 @@ The `ensure` parameter accepts three attributes: absent, present, and latest. L

The password used to protect the keystore. If private keys are also protected, this password will be used to attempt to unlock them.

#### `password_file`

Used as an alternative to `password` here you can specify a plaintext file where the password is stored.

#### `path`

The search path used for command (keytool, openssl) execution. Paths can be specified as an array or as a file path seperated list (for example : in linux).

#### `private_key`

If you want an application to be a server and encrypt traffic, you will need a private key. Private key entries in a keystore must be accompanied by a signed certificate for the keytool provider.
Expand Down Expand Up @@ -132,10 +142,3 @@ Puppet Labs modules on the Puppet Forge are open projects, and community contrib
We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.

You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing)

Release Notes
-------------

**0.0.6**

Fixes an issue with ibm java handling input from stdin on SLES
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require 'rubygems'
require 'puppetlabs_spec_helper/rake_tasks'
28 changes: 19 additions & 9 deletions lib/puppet/provider/java_ks/keytool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ def to_pkcs12
return output
end

def password_file
if @resource[:password_file].nil?
tmpfile = Tempfile.new("#{@resource[:name]}.")
if File.exists?(@resource[:target]) and not File.zero?(@resource[:target])
tmpfile.write("#{@resource[:password]}\n#{@resource[:password]}")
else
tmpfile.write("#{@resource[:password]}\n#{@resource[:password]}\n#{@resource[:password]}")
end
tmpfile.flush
tmpfile
else
@resource[:password_file]
end
end

# Where we actually to the import of the file created using to_pkcs12.
def import_ks
tmppk12 = Tempfile.new("#{@resource[:name]}.")
Expand All @@ -50,16 +65,11 @@ def import_ks
'-alias', @resource[:name]
]
cmd << '-trustcacerts' if @resource[:trustcacerts] == :true
tmpfile = Tempfile.new("#{@resource[:name]}.")
if File.exists?(@resource[:target]) and not File.zero?(@resource[:target])
tmpfile.write("#{@resource[:password]}\n#{@resource[:password]}")
else
tmpfile.write("#{@resource[:password]}\n#{@resource[:password]}\n#{@resource[:password]}")
end
tmpfile.flush
run_command(cmd, @resource[:target], tmpfile)

pwfile = password_file
run_command(cmd, @resource[:target], pwfile)
tmppk12.close!
tmpfile.close!
pwfile.close! if pwfile.is_a? Tempfile
end

def exists?
Expand Down
19 changes: 16 additions & 3 deletions lib/puppet/type/java_ks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ def insync?(is)

newparam(:password) do
desc 'The password used to protect the keystore. If private keys are
sebsequently also protected this password will be used to attempt
unlocking...P.S. Let me know if you eve need a seperate private key
subsequently also protected this password will be used to attempt
unlocking...P.S. Let me know if you ever need a separate private key
password parameter...'
end

isrequired
newparam(:password_file) do
desc 'The path to a file containing the password used to protect the
keystore. This cannot be used together with :password.'
end

newparam(:trustcacerts) do
Expand Down Expand Up @@ -148,5 +151,15 @@ def self.title_patterns
]
]
end

validate do
if value(:password) and value(:password_file)
self.fail "You must pass either 'password' or 'password_file', not both."
end

unless value(:password) or value(:password_file)
self.fail "You must pass one of 'password' or 'password_file'."
end
end
end
end
73 changes: 36 additions & 37 deletions spec/unit/puppet/provider/java_ks/keytool_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,33 @@

describe Puppet::Type.type(:java_ks).provider(:keytool) do

before do
@app_example_com = {
:title => 'app.example.com:/tmp/application.jks',
:name => 'app.example.com',
:target => '/tmp/application.jks',
:password => 'puppet',
:certificate => '/tmp/app.example.com.pem',
:private_key => '/tmp/private/app.example.com.pem',
:provider => described_class.name
let(:params) do
{
:title => 'app.example.com:/tmp/application.jks',
:name => 'app.example.com',
:target => '/tmp/application.jks',
:password => 'puppet',
:certificate => '/tmp/app.example.com.pem',
:private_key => '/tmp/private/app.example.com.pem',
:provider => described_class.name
}
end

let(:resource) do
Puppet::Type.type(:java_ks).new(params)
end

let(:provider) do
resource.provider
end

before do
provider.stubs(:command).with(:keytool).returns('mykeytool')
provider.stubs(:command).with(:openssl).returns('myopenssl')

provider.stubs(:command_keytool).returns 'mykeytool'
provider.stubs(:command_openssl).returns 'myopenssl'

tempfile = stub('tempfile', :class => Tempfile,
:write => true,
:flush => true,
Expand All @@ -25,18 +39,6 @@
Tempfile.stubs(:new).returns(tempfile)
end

let(:resource) do
Puppet::Type.type(:java_ks).new @app_example_com
end

let(:provider) do
resource.provider
end

let(:app_example_com) do
@app_example_com
end

describe 'when updating a certificate' do
it 'should call destroy and create' do
provider.expects(:destroy)
Expand All @@ -47,22 +49,21 @@

describe 'when importing a private key and certifcate' do
it 'should execute openssl and keytool with specific options' do
provider.expects(:run_command).with do |*args|
args[0] == [
provider.expects(:run_command).with([
'myopenssl', 'pkcs12', '-export', '-passout', 'stdin',
'-in', resource[:certificate],
'-inkey', resource[:private_key],
'-name', resource[:name]
]
end
provider.expects(:run_command).with do |*args|
args[0] == [
],
any_parameters
)
provider.expects(:run_command).with([
'mykeytool', '-importkeystore', '-srcstoretype', 'PKCS12',
'-destkeystore', resource[:target],
'-srckeystore', '/tmp/testing.stuff',
'-alias', resource[:name]
]
end
], any_parameters
)
provider.import_ks
end
end
Expand All @@ -76,28 +77,26 @@
it 'should call keytool with specific options if only certificate is provided' do
no_pk = resource.dup
no_pk.delete(:private_key)
provider.expects(:run_command).with do |*args|
args[0] == [
provider.expects(:run_command).with([
'mykeytool', '-importcert', '-noprompt',
'-alias', no_pk[:name],
'-file', no_pk[:certificate],
'-keystore', no_pk[:target]
]
end
], any_parameters
)
no_pk.provider.expects(:import_ks).never
no_pk.provider.create
end
end

describe 'when removing entries from keytool' do
it 'should execute keytool with a specific set of options' do
provider.expects(:run_command).with do |*args|
args[0] == [
provider.expects(:run_command).with([
'mykeytool', '-delete',
'-alias', resource[:name],
'-keystore', resource[:target]
]
end
], any_parameters
)
provider.destroy
end
end
Expand Down
20 changes: 18 additions & 2 deletions spec/unit/puppet/type/java_ks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
Puppet::Type.type(:java_ks).new(@app_example_com)[:ensure].should == :present
end

describe 'when validating arttibutes' do
describe 'when validating attributes' do

[:name, :target, :private_key, :certificate, :password, :trustcacerts].each do |param|
[:name, :target, :private_key, :certificate, :password, :password_file, :trustcacerts].each do |param|
it "should have a #{param} parameter" do
Puppet::Type.type(:java_ks).attrtype(param).should == :param
end
Expand Down Expand Up @@ -73,6 +73,22 @@
it 'should have :false value to :trustcacerts when parameter not provided' do
Puppet::Type.type(:java_ks).new(jks_resource)[:trustcacerts].should == :false
end

it 'should fail if both :password and :password_file are provided' do
jks = jks_resource.dup
jks[:password_file] = '/path/to/password_file'
expect {
Puppet::Type.type(:java_ks).new(jks)
}.to raise_error(Puppet::Error, /You must pass either/)
end

it 'should fail if neither :password or :password_file is provided' do
jks = jks_resource.dup
jks.delete(:password)
expect {
Puppet::Type.type(:java_ks).new(jks)
}.to raise_error(Puppet::Error, /You must pass one of/)
end
end

describe 'when ensure is set to latest' do
Expand Down