add a kegeneration function

This commit is contained in:
mh 2010-12-29 20:12:51 +01:00
parent da1978bbba
commit d506e8a652
4 changed files with 154 additions and 0 deletions

View file

@ -0,0 +1,28 @@
Puppet::Parser::Functions::newfunction(:tinc_keygen, :type => :rvalue, :doc =>
"Returns an array containing the tinc private and public (in this order) key
for a certain private key path.
It will generate the keypair if both do not exist. It will also generate
the directory hierarchy if required.
It accepts only fully qualified paths, everything else will fail.") do |args|
raise Puppet::ParseError, "Wrong number of arguments" if args.to_a.length < 1 || args.to_a.length > 2
name = args.to_a[0]
if args.to_a.length > 1
dir = args.to_a[1]
raise Puppet::ParseError, "Only fully qualified paths are accepted (#{dir})" unless dir =~ /^\/.+/
else
dir = File.join('/etc/tinc',name)
end
private_key_path = File.join(dir,"rsa_key.priv")
public_key_path = File.join(dir,"rsa_key.pub")
raise Puppet::ParseError, "Either only the private or only the public key exists" if File.exists?(private_key_path) ^ File.exists?(public_key_path)
[private_key_path,public_key_path].each do |path|
raise Puppet::ParseError, "#{path} is a directory" if File.directory?(path)
end
Puppet::Util.recmkdir(dir,0700) unless File.directory?(dir)
unless [private_key_path,public_key_path].all?{|path| File.exists?(path) }
output = Puppet::Util.execute(['/usr/sbin/tincd', '-c', dir, '-n', name, '-K'])
raise Puppet::ParseError, "Something went wrong during key generation! Output: #{output}" unless output =~ /Generating .* bits keys/
end
[File.read(private_key_path),File.read(public_key_path)]
end

6
spec/spec.opts Normal file
View file

@ -0,0 +1,6 @@
--format
s
--colour
--loadby
mtime
--backtrace

16
spec/spec_helper.rb Normal file
View file

@ -0,0 +1,16 @@
require 'pathname'
dir = Pathname.new(__FILE__).parent
$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib')
require 'puppet'
gem 'rspec', '>= 1.2.9'
require 'spec/autorun'
Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each do |support_file|
require support_file
end
# We need this because the RAL uses 'should' as a method. This
# allows us the same behaviour but with a different method name.
class Object
alias :must :should
end

View file

@ -0,0 +1,104 @@
#! /usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'mocha'
require 'fileutils'
describe "the tinc_keygen function" do
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("tinc_keygen").should == "function_tinc_keygen"
end
it "should raise a ParseError if no argument is passed" do
lambda { @scope.function_tinc_keygen([]) }.should( raise_error(Puppet::ParseError))
end
it "should raise a ParseError if there is more than 2 arguments" do
lambda { @scope.function_tinc_keygen(["foo", "bar", "foo"]) }.should( raise_error(Puppet::ParseError))
end
it "should raise a ParseError if the second argument is not fully qualified" do
lambda { @scope.function_tinc_keygen(["foo","bar"]) }.should( raise_error(Puppet::ParseError))
end
it "should raise a ParseError if the private key path is a directory" do
File.stubs(:directory?).with("/some_dir/rsa_key.priv").returns(true)
lambda { @scope.function_tinc_keygen(['foo',"/some_dir"]) }.should( raise_error(Puppet::ParseError))
end
it "should raise a ParseError if the public key path is a directory" do
File.stubs(:directory?).with("/some_dir/rsa_key.pub").returns(true)
lambda { @scope.function_tinc_keygen(['foo',"/some_dir"]) }.should( raise_error(Puppet::ParseError))
end
describe "when executing properly" do
before do
File.stubs(:directory?).with('/tmp/a/b/rsa_key.priv').returns(false)
File.stubs(:directory?).with('/tmp/a/b/rsa_key.pub').returns(false)
File.stubs(:read).with('/tmp/a/b/rsa_key.priv').returns('privatekey')
File.stubs(:read).with('/tmp/a/b/rsa_key.pub').returns('publickey')
end
it "should fail if the public but not the private key exists" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(true)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(false)
lambda { @scope.function_tinc_keygen(['foo',"/tmp/a/b"]) }.should( raise_error(Puppet::ParseError))
end
it "should fail if the private but not the public key exists" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(true)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(false)
lambda { @scope.function_tinc_keygen(['foo',"/tmp/a/b"]) }.should( raise_error(Puppet::ParseError))
end
it "should return an array of size 2 with the right content if the keyfiles exists" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(true)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(true)
File.stubs(:directory?).with('/tmp/a/b').returns(true)
Puppet::Util.expects(:execute).never
result = @scope.function_tinc_keygen(['foo','/tmp/a/b'])
result.length.should == 2
result[0].should == 'privatekey'
result[1].should == 'publickey'
end
it "should create the directory path if it does not exist" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(false)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(false)
File.stubs(:directory?).with("/tmp/a/b").returns(false)
Puppet::Util.expects(:recmkdir).with("/tmp/a/b",0700)
Puppet::Util.expects(:execute).returns("foo\nbar\nGenerating 2048 bits keys\n++++\n---")
result = @scope.function_tinc_keygen(['foo','/tmp/a/b'])
result.length.should == 2
result[0].should == 'privatekey'
result[1].should == 'publickey'
end
it "should generate the key if the keyfiles do not exist" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(false)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(false)
File.stubs(:directory?).with("/tmp/a/b").returns(true)
Puppet::Util.expects(:execute).with(['/usr/sbin/tincd','-c', '/tmp/a/b', '-n', 'foo', '-K']).returns("foo\nbar\nGenerating 2048 bits keys\n++++\n---")
result = @scope.function_tinc_keygen(['foo','/tmp/a/b'])
result.length.should == 2
result[0].should == 'privatekey'
result[1].should == 'publickey'
end
it "should fail if something goes wrong during generation" do
File.stubs(:exists?).with("/tmp/a/b/rsa_key.priv").returns(false)
File.stubs(:exists?).with("/tmp/a/b/rsa_key.pub").returns(false)
File.stubs(:directory?).with("/tmp/a/b").returns(true)
Puppet::Util.expects(:execute).with(['/usr/sbin/tincd','-c', '/tmp/a/b', '-n', 'foo', '-K']).returns("something is wrong")
lambda { @scope.function_tinc_keygen(['foo',"/tmp/a/b"]) }.should( raise_error(Puppet::ParseError))
end
end
end