summaryrefslogtreecommitdiff
path: root/puppet/modules/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'puppet/modules/openvpn')
-rw-r--r--puppet/modules/openvpn/.fixtures.yml6
-rw-r--r--puppet/modules/openvpn/.gitignore2
-rw-r--r--puppet/modules/openvpn/.gitrepo11
-rw-r--r--puppet/modules/openvpn/Modulefile11
-rw-r--r--puppet/modules/openvpn/Rakefile2
-rw-r--r--puppet/modules/openvpn/Readme.markdown123
-rw-r--r--puppet/modules/openvpn/manifests/client.pp142
-rw-r--r--puppet/modules/openvpn/manifests/init.pp45
-rw-r--r--puppet/modules/openvpn/manifests/option.pp24
-rw-r--r--puppet/modules/openvpn/manifests/server.pp153
-rw-r--r--puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb20
-rw-r--r--puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb116
-rw-r--r--puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb42
-rw-r--r--puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb109
-rw-r--r--puppet/modules/openvpn/spec/spec_helper.rb2
-rw-r--r--puppet/modules/openvpn/templates/etc-default-openvpn.erb20
-rw-r--r--puppet/modules/openvpn/templates/vars.erb69
17 files changed, 897 insertions, 0 deletions
diff --git a/puppet/modules/openvpn/.fixtures.yml b/puppet/modules/openvpn/.fixtures.yml
new file mode 100644
index 00000000..1125ecca
--- /dev/null
+++ b/puppet/modules/openvpn/.fixtures.yml
@@ -0,0 +1,6 @@
+fixtures:
+ repositories:
+ concat: git://github.com/ripienaar/puppet-concat.git
+ symlinks:
+ openvpn: "#{source_dir}"
+
diff --git a/puppet/modules/openvpn/.gitignore b/puppet/modules/openvpn/.gitignore
new file mode 100644
index 00000000..12c29e7d
--- /dev/null
+++ b/puppet/modules/openvpn/.gitignore
@@ -0,0 +1,2 @@
+pkg
+spec/fixtures
diff --git a/puppet/modules/openvpn/.gitrepo b/puppet/modules/openvpn/.gitrepo
new file mode 100644
index 00000000..54c861da
--- /dev/null
+++ b/puppet/modules/openvpn/.gitrepo
@@ -0,0 +1,11 @@
+; DO NOT EDIT (unless you know what you are doing)
+;
+; This subdirectory is a git "subrepo", and this file is maintained by the
+; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
+;
+[subrepo]
+ remote = https://leap.se/git/puppet_openvpn
+ branch = master
+ commit = ba7ec7abd25cd4c5031e11cd3ae17872ef31b24b
+ parent = d6719731dce8ee7e048a16a447a426abcaa44f24
+ cmdver = 0.3.0
diff --git a/puppet/modules/openvpn/Modulefile b/puppet/modules/openvpn/Modulefile
new file mode 100644
index 00000000..55b6eba0
--- /dev/null
+++ b/puppet/modules/openvpn/Modulefile
@@ -0,0 +1,11 @@
+name 'luxflux-openvpn'
+version '1.0.2'
+source 'https://github.com/luxflux/puppet-openvpn'
+author 'luxflux'
+license 'UNKNOWN'
+summary 'UNKNOWN'
+description 'UNKNOWN'
+project_page 'UNKNOWN'
+
+## Add dependencies, if any:
+dependency 'ripienaar/concat'
diff --git a/puppet/modules/openvpn/Rakefile b/puppet/modules/openvpn/Rakefile
new file mode 100644
index 00000000..14f1c246
--- /dev/null
+++ b/puppet/modules/openvpn/Rakefile
@@ -0,0 +1,2 @@
+require 'rubygems'
+require 'puppetlabs_spec_helper/rake_tasks'
diff --git a/puppet/modules/openvpn/Readme.markdown b/puppet/modules/openvpn/Readme.markdown
new file mode 100644
index 00000000..d2a1f67b
--- /dev/null
+++ b/puppet/modules/openvpn/Readme.markdown
@@ -0,0 +1,123 @@
+# OpenVPN Puppet module
+
+OpenVPN module for puppet including client config/cert creation (tarball to download)
+
+## Dependencies
+ - [puppet-concat](https://github.com/ripienaar/puppet-concat)
+
+## Supported OS
+ - Debian Squeeze (should, as it works on Ubuntu Lucid)
+ - Ubuntu 10.4, 12.04 (other untested)
+ - CentOS
+
+## Example
+
+ # add a server instance
+ openvpn::server {
+ "server1":
+ country => "CH",
+ province => "ZH",
+ city => "Winterthur",
+ organization => "example.org",
+ email => "root@example.org";
+ }
+
+ # configure server
+ openvpn::option {
+ "dev server1":
+ key => "dev",
+ value => "tun0",
+ server => "server1";
+ "script-security server1":
+ key => "script-security",
+ value => "3",
+ server => "server1";
+ "daemon server1":
+ key => "daemon",
+ server => "server1";
+ "keepalive server1":
+ key => "keepalive",
+ value => "10 60",
+ server => "server1";
+ "ping-timer-rem server1":
+ key => "ping-timer-rem",
+ server => "server1";
+ "persist-tun server1":
+ key => "persist-tun",
+ server => "server1";
+ "persist-key server1":
+ key => "persist-key",
+ server => "server1";
+ "proto server1":
+ key => "proto",
+ value => "tcp-server",
+ server => "server1";
+ "cipher server1":
+ key => "cipher",
+ value => "BF-CBC",
+ server => "server1";
+ "local server1":
+ key => "local",
+ value => $ipaddress,
+ server => "server1";
+ "tls-server server1":
+ key => "tls-server",
+ server => "server1";
+ "server server1":
+ key => "server",
+ value => "10.10.10.0 255.255.255.0",
+ server => "server1";
+ "lport server1":
+ key => "lport",
+ value => "1194",
+ server => "server1";
+ "management server1":
+ key => "management",
+ value => "/var/run/openvpn-server1.sock unix",
+ server => "server1";
+ "comp-lzo server1":
+ key => "comp-lzo",
+ server => "server1";
+ "topology server1":
+ key => "topology",
+ value => "subnet",
+ server => "server1";
+ "client-to-client server1":
+ key => "client-to-client",
+ server => "server1";
+ }
+
+
+ # define clients
+ openvpn::client {
+ [ "client1.example.org", "client2.example.org" ]:
+ server => "server1";
+ }
+
+ # add options to the client-config-dir file
+ openvpn::option {
+ "iroute server1 client1.example.org home network":
+ key => "iroute",
+ value => "192.168.0.0 255.255.255.0",
+ client => "client1.example.org",
+ server => "server1",
+ csc => true;
+ }
+
+ # add an option to the client config
+ openvpn::option {
+ "ifconfig server1 client2.example.org":
+ key => "ifconfig-push",
+ value => "10.10.10.2 255.255.255.0",
+ client => "client2.example.org",
+ server => "server1";
+ }
+
+Don't forget the [sysctl](https://github.com/luxflux/puppet-sysctl) directive ```net.ipv4.ip_forward```!
+
+
+# Contributors
+
+These fine folks helped to get this far with this module:
+* [@jlk](https://github.com/jlk)
+* [@jlambert121](https://github.com/jlambert121)
diff --git a/puppet/modules/openvpn/manifests/client.pp b/puppet/modules/openvpn/manifests/client.pp
new file mode 100644
index 00000000..ed11b3a9
--- /dev/null
+++ b/puppet/modules/openvpn/manifests/client.pp
@@ -0,0 +1,142 @@
+# client.pp
+
+define openvpn::client($server, $remote_host = $::fqdn) {
+ exec {
+ "generate certificate for ${name} in context of ${server}":
+ command => ". ./vars && ./pkitool ${name}",
+ cwd => "/etc/openvpn/${server}/easy-rsa",
+ creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt",
+ provider => 'shell',
+ require => Exec["generate server cert ${server}"];
+ }
+
+ file {
+ "/etc/openvpn/${server}/download-configs/${name}":
+ ensure => directory,
+ require => File["/etc/openvpn/${server}/download-configs"];
+
+ "/etc/openvpn/${server}/download-configs/${name}/keys":
+ ensure => directory,
+ require => File["/etc/openvpn/${server}/download-configs/${name}"];
+
+ "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt":
+ ensure => link,
+ target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt",
+ require => [ Exec["generate certificate for ${name} in context of ${server}"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys"] ];
+
+ "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key":
+ ensure => link,
+ target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key",
+ require => [ Exec["generate certificate for ${name} in context of ${server}"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys"] ];
+
+ "/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt":
+ ensure => link,
+ target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt",
+ require => [ Exec["generate certificate for ${name} in context of ${server}"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys"] ];
+ }
+
+
+ openvpn::option {
+ "ca ${server} with ${name}":
+ key => 'ca',
+ value => 'keys/ca.crt',
+ client => $name,
+ server => $server;
+ "cert ${server} with ${name}":
+ key => 'cert',
+ value => "keys/${name}.crt",
+ client => $name,
+ server => $server;
+ "key ${server} with ${name}":
+ key => 'key',
+ value => "keys/${name}.key",
+ client => $name,
+ server => $server;
+ "client ${server} with ${name}":
+ key => 'client',
+ client => $name,
+ server => $server;
+ "dev ${server} with ${name}":
+ key => 'dev',
+ value => 'tun',
+ client => $name,
+ server => $server;
+ "proto ${server} with ${name}":
+ key => 'proto',
+ value => 'tcp',
+ client => $name,
+ server => $server;
+ "remote ${server} with ${name}":
+ key => 'remote',
+ value => "${remote_host} 1194",
+ client => $name,
+ server => $server;
+ "resolv-retry ${server} with ${name}":
+ key => 'resolv-retry',
+ value => 'infinite',
+ client => $name,
+ server => $server;
+ "nobind ${server} with ${name}":
+ key => 'nobind',
+ client => $name,
+ server => $server;
+ "persist-key ${server} with ${name}":
+ key => 'persist-key',
+ client => $name,
+ server => $server;
+ "persist-tun ${server} with ${name}":
+ key => 'persist-tun',
+ client => $name,
+ server => $server;
+ "mute-replay-warnings ${server} with ${name}":
+ key => 'mute-replay-warnings',
+ client => $name,
+ server => $server;
+ "ns-cert-type ${server} with ${name}":
+ key => 'ns-cert-type',
+ value => 'server',
+ client => $name,
+ server => $server;
+ "comp-lzo ${server} with ${name}":
+ key => 'comp-lzo',
+ client => $name,
+ server => $server;
+ "verb ${server} with ${name}":
+ key => 'verb',
+ value => '3',
+ client => $name,
+ server => $server;
+ "mute ${server} with ${name}":
+ key => 'mute',
+ value => '20',
+ client => $name,
+ server => $server;
+ }
+
+ exec {
+ "tar the thing ${server} with ${name}":
+ cwd => "/etc/openvpn/${server}/download-configs/",
+ command => "/bin/rm ${name}.tar.gz; tar --exclude=\\*.conf.d -chzvf ${name}.tar.gz ${name}",
+ refreshonly => true,
+ require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"],
+ File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"] ];
+ }
+
+
+ concat {
+ [ "/etc/openvpn/${server}/client-configs/${name}", "/etc/openvpn/${server}/download-configs/${name}/${name}.conf" ]:
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ force => true,
+ notify => Exec["tar the thing ${server} with ${name}"],
+ require => [ File['/etc/openvpn'], File["/etc/openvpn/${server}/download-configs/${name}"] ];
+ }
+
+}
diff --git a/puppet/modules/openvpn/manifests/init.pp b/puppet/modules/openvpn/manifests/init.pp
new file mode 100644
index 00000000..a3dd70c0
--- /dev/null
+++ b/puppet/modules/openvpn/manifests/init.pp
@@ -0,0 +1,45 @@
+# openvpn.pp
+
+class openvpn {
+ package {
+ 'openvpn':
+ ensure => installed;
+ }
+ service {
+ 'openvpn':
+ ensure => running,
+ enable => true,
+ hasrestart => true,
+ hasstatus => true,
+ require => Exec['concat_/etc/default/openvpn'];
+ }
+ file {
+ '/etc/openvpn':
+ ensure => directory,
+ require => Package['openvpn'];
+ }
+ file {
+ '/etc/openvpn/keys':
+ ensure => directory,
+ require => File['/etc/openvpn'];
+ }
+
+ include concat::setup
+
+ concat {
+ '/etc/default/openvpn':
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ notify => Service['openvpn'];
+ }
+
+ concat::fragment {
+ 'openvpn.default.header':
+ content => template('openvpn/etc-default-openvpn.erb'),
+ target => '/etc/default/openvpn',
+ order => 01;
+ }
+
+}
diff --git a/puppet/modules/openvpn/manifests/option.pp b/puppet/modules/openvpn/manifests/option.pp
new file mode 100644
index 00000000..eb3d5a72
--- /dev/null
+++ b/puppet/modules/openvpn/manifests/option.pp
@@ -0,0 +1,24 @@
+# option.pp
+
+define openvpn::option($key, $server, $value = '', $client = '', $csc = false) {
+ $content = $value ? {
+ '' => $key,
+ default => "${key} ${value}"
+ }
+
+ if $client == '' {
+ $path = "/etc/openvpn/${server}.conf"
+ } else {
+ if $csc {
+ $path = "/etc/openvpn/${server}/client-configs/${client}"
+ } else {
+ $path = "/etc/openvpn/${server}/download-configs/${client}/${client}.conf"
+ }
+ }
+
+ concat::fragment {
+ "openvpn.${server}.${client}.${name}":
+ target => $path,
+ content => "${content}\n";
+ }
+}
diff --git a/puppet/modules/openvpn/manifests/server.pp b/puppet/modules/openvpn/manifests/server.pp
new file mode 100644
index 00000000..bfcaad83
--- /dev/null
+++ b/puppet/modules/openvpn/manifests/server.pp
@@ -0,0 +1,153 @@
+# server.pp
+
+define openvpn::server($country, $province, $city, $organization, $email) {
+ include openvpn
+
+ $easyrsa_source = $::osfamily ? {
+ 'RedHat' => '/usr/share/doc/openvpn-2.2.2/easy-rsa/2.0',
+ default => '/usr/share/doc/openvpn/examples/easy-rsa/2.0'
+ }
+
+ $link_openssl_cnf = $::osfamily ? {
+ /(Debian|RedHat)/ => true,
+ default => false
+ }
+
+ file {
+ "/etc/openvpn/${name}":
+ ensure => directory,
+ require => Package['openvpn'];
+ }
+ file {
+ "/etc/openvpn/${name}/client-configs":
+ ensure => directory,
+ require => File["/etc/openvpn/${name}"];
+ "/etc/openvpn/${name}/download-configs":
+ ensure => directory,
+ require => File["/etc/openvpn/${name}"];
+ }
+
+ openvpn::option {
+ "client-config-dir ${name}":
+ key => 'client-config-dir',
+ value => "/etc/openvpn/${name}/client-configs",
+ server => $name,
+ require => File["/etc/openvpn/${name}"];
+ "mode ${name}":
+ key => 'mode',
+ value => 'server',
+ server => $name;
+ }
+
+ exec {
+ "copy easy-rsa to openvpn config folder ${name}":
+ command => "/bin/cp -r ${easyrsa_source} /etc/openvpn/${name}/easy-rsa",
+ creates => "/etc/openvpn/${name}/easy-rsa",
+ notify => Exec['fix_easyrsa_file_permissions'],
+ require => File["/etc/openvpn/${name}"];
+ }
+ exec {
+ 'fix_easyrsa_file_permissions':
+ refreshonly => true,
+ command => "/bin/chmod 755 /etc/openvpn/${name}/easy-rsa/*";
+ }
+ file {
+ "/etc/openvpn/${name}/easy-rsa/vars":
+ ensure => present,
+ content => template('openvpn/vars.erb'),
+ require => Exec["copy easy-rsa to openvpn config folder ${name}"];
+ }
+
+ file {
+ "/etc/openvpn/${name}/easy-rsa/openssl.cnf":
+ require => Exec["copy easy-rsa to openvpn config folder ${name}"];
+ }
+ if $link_openssl_cnf == true {
+ File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] {
+ ensure => link,
+ target => "/etc/openvpn/${name}/easy-rsa/openssl-1.0.0.cnf"
+ }
+ }
+
+ exec {
+ "generate dh param ${name}":
+ command => '. ./vars && ./clean-all && ./build-dh',
+ cwd => "/etc/openvpn/${name}/easy-rsa",
+ creates => "/etc/openvpn/${name}/easy-rsa/keys/dh1024.pem",
+ provider => 'shell',
+ require => File["/etc/openvpn/${name}/easy-rsa/vars"];
+
+ "initca ${name}":
+ command => '. ./vars && ./pkitool --initca',
+ cwd => "/etc/openvpn/${name}/easy-rsa",
+ creates => "/etc/openvpn/${name}/easy-rsa/keys/ca.key",
+ provider => 'shell',
+ require => [ Exec["generate dh param ${name}"], File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] ];
+
+ "generate server cert ${name}":
+ command => '. ./vars && ./pkitool --server server',
+ cwd => "/etc/openvpn/${name}/easy-rsa",
+ creates => "/etc/openvpn/${name}/easy-rsa/keys/server.key",
+ provider => 'shell',
+ require => Exec["initca ${name}"];
+ }
+
+ file {
+ "/etc/openvpn/${name}/keys":
+ ensure => link,
+ target => "/etc/openvpn/${name}/easy-rsa/keys",
+ require => Exec["copy easy-rsa to openvpn config folder ${name}"];
+ }
+
+ openvpn::option {
+ "ca ${name}":
+ key => 'ca',
+ value => "/etc/openvpn/${name}/keys/ca.crt",
+ require => Exec["initca ${name}"],
+ server => $name;
+ "cert ${name}":
+ key => 'cert',
+ value => "/etc/openvpn/${name}/keys/server.crt",
+ require => Exec["generate server cert ${name}"],
+ server => $name;
+ "key ${name}":
+ key => 'key',
+ value => "/etc/openvpn/${name}/keys/server.key",
+ require => Exec["generate server cert ${name}"],
+ server => $name;
+ "dh ${name}":
+ key => 'dh',
+ value => "/etc/openvpn/${name}/keys/dh1024.pem",
+ require => Exec["generate dh param ${name}"],
+ server => $name;
+
+ "proto ${name}":
+ key => 'proto',
+ value => 'tcp',
+ require => Exec["generate dh param ${name}"],
+ server => $name;
+
+ "comp-lzo ${name}":
+ key => 'comp-lzo',
+ require => Exec["generate dh param ${name}"],
+ server => $name;
+ }
+
+ concat::fragment {
+ "openvpn.default.autostart.${name}":
+ content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n",
+ target => '/etc/default/openvpn',
+ order => 10;
+ }
+
+ concat {
+ "/etc/openvpn/${name}.conf":
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ require => File['/etc/openvpn'],
+ notify => Service['openvpn'];
+ }
+
+}
diff --git a/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb
new file mode 100644
index 00000000..cdfdea19
--- /dev/null
+++ b/puppet/modules/openvpn/spec/classes/openvpn_init_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe 'openvpn', :type => :class do
+
+ let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } }
+
+ it { should create_class('openvpn') }
+ it { should contain_class('concat::setup') }
+ it { should contain_package('openvpn') }
+ it { should contain_service('openvpn').with(
+ 'ensure' => 'running',
+ 'enable' => true
+ ) }
+
+ it { should contain_file('/etc/openvpn').with('ensure' => 'directory') }
+ it { should contain_file('/etc/openvpn/keys').with('ensure' => 'directory') }
+
+ it { should contain_concat__fragment('openvpn.default.header') }
+
+end
diff --git a/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb
new file mode 100644
index 00000000..da71d63d
--- /dev/null
+++ b/puppet/modules/openvpn/spec/defines/openvpn_client_spec.rb
@@ -0,0 +1,116 @@
+require 'spec_helper'
+
+describe 'openvpn::client', :type => :define do
+ let(:title) { 'test_client' }
+ let(:params) { { 'server' => 'test_server' } }
+ let(:facts) { { :fqdn => 'somehost', :concat_basedir => '/var/lib/puppet/concat' } }
+
+ it { should contain_exec('generate certificate for test_client in context of test_server') }
+
+ [ 'test_client', 'test_client/keys'].each do |directory|
+ it { should contain_file("/etc/openvpn/test_server/download-configs/#{directory}") }
+ end
+
+ [ 'test_client.crt', 'test_client.key', 'ca.crt' ].each do |file|
+ it { should contain_file("/etc/openvpn/test_server/download-configs/test_client/keys/#{file}").with(
+ 'ensure' => 'link',
+ 'target' => "/etc/openvpn/test_server/easy-rsa/keys/#{file}"
+ )}
+ end
+
+ it { should contain_exec('tar the thing test_server with test_client').with(
+ 'cwd' => '/etc/openvpn/test_server/download-configs/',
+ 'command' => '/bin/rm test_client.tar.gz; tar --exclude=\*.conf.d -chzvf test_client.tar.gz test_client'
+ ) }
+
+ it { should contain_openvpn__option('ca test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'ca',
+ 'value' => 'keys/ca.crt'
+ )}
+ it { should contain_openvpn__option('cert test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'cert',
+ 'value' => 'keys/test_client.crt'
+ )}
+ it { should contain_openvpn__option('key test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'key',
+ 'value' => 'keys/test_client.key'
+ )}
+ it { should contain_openvpn__option('client test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'client'
+ )}
+ it { should contain_openvpn__option('dev test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'dev',
+ 'value' => 'tun'
+ )}
+ it { should contain_openvpn__option('proto test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'proto',
+ 'value' => 'tcp'
+ )}
+ it { should contain_openvpn__option('remote test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'remote',
+ 'value' => 'somehost 1194'
+ )}
+ it { should contain_openvpn__option('resolv-retry test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'resolv-retry',
+ 'value' => 'infinite'
+ )}
+ it { should contain_openvpn__option('nobind test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'nobind'
+ )}
+ it { should contain_openvpn__option('persist-key test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'persist-key'
+ )}
+ it { should contain_openvpn__option('persist-tun test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'persist-tun'
+ )}
+ it { should contain_openvpn__option('mute-replay-warnings test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'mute-replay-warnings'
+ )}
+ it { should contain_openvpn__option('ns-cert-type test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'ns-cert-type',
+ 'value' => 'server'
+ )}
+ it { should contain_openvpn__option('comp-lzo test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'comp-lzo'
+ )}
+ it { should contain_openvpn__option('verb test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'verb',
+ 'value' => '3'
+ )}
+ it { should contain_openvpn__option('mute test_server with test_client').with(
+ 'server' => 'test_server',
+ 'client' => 'test_client',
+ 'key' => 'mute',
+ 'value' => '20'
+ )}
+end
diff --git a/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb
new file mode 100644
index 00000000..a2d1661d
--- /dev/null
+++ b/puppet/modules/openvpn/spec/defines/openvpn_option_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+
+describe 'openvpn::option', :type => :define do
+
+ let(:title) { 'test_param' }
+
+ context "when key => 'test_key', server => 'test_server'" do
+ let(:params) { { 'key' => 'test_key', 'server' => 'test_server' } }
+
+ it { should contain_concat__fragment('openvpn.test_server..test_param').with(
+ 'target' => '/etc/openvpn/test_server.conf',
+ 'content' => "test_key\n"
+ ) }
+ end
+
+ context "when key => 'test_key', value => 'test_value', server => 'test_server'" do
+ let(:params) { { 'key' => 'test_key', 'value' => 'test_value', 'server' => 'test_server' } }
+
+ it { should contain_concat__fragment('openvpn.test_server..test_param').with(
+ 'target' => '/etc/openvpn/test_server.conf',
+ 'content' => "test_key test_value\n"
+ ) }
+ end
+
+ context "when key => 'test_key', server => 'test_server', client => 'test_client'" do
+ let(:params) { { 'key' => 'test_key', 'server' => 'test_server', 'client' => 'test_client' } }
+
+ it { should contain_concat__fragment('openvpn.test_server.test_client.test_param').with(
+ 'target' => '/etc/openvpn/test_server/download-configs/test_client/test_client.conf',
+ 'content' => "test_key\n"
+ ) }
+ end
+
+ context "when key => 'test_key', server => 'test_server', client => 'test_client', csc => true" do
+ let(:params) { { 'key' => 'test_key', 'server' => 'test_server', 'client' => 'test_client', 'csc' => 'true' } }
+
+ it { should contain_concat__fragment('openvpn.test_server.test_client.test_param').with(
+ 'target' => '/etc/openvpn/test_server/client-configs/test_client',
+ 'content' => "test_key\n"
+ ) }
+ end
+end
diff --git a/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb
new file mode 100644
index 00000000..1032302e
--- /dev/null
+++ b/puppet/modules/openvpn/spec/defines/openvpn_server_spec.rb
@@ -0,0 +1,109 @@
+require 'spec_helper'
+
+describe 'openvpn::server', :type => :define do
+
+ let(:title) { 'test_server' }
+ let(:params) { {
+ 'country' => 'CO',
+ 'province' => 'ST',
+ 'city' => 'Some City',
+ 'organization' => 'example.org',
+ 'email' => 'testemail@example.org'
+ } }
+
+ let (:facts) { { :concat_basedir => '/var/lib/puppet/concat' } }
+
+ # Files associated with a server config
+ it { should contain_file('/etc/openvpn/test_server').with('ensure' => 'directory')}
+ it { should contain_file('/etc/openvpn/test_server/client-configs').with('ensure' => 'directory')}
+ it { should contain_file('/etc/openvpn/test_server/download-configs').with('ensure' => 'directory')}
+ it { should contain_file('/etc/openvpn/test_server/easy-rsa/vars')}
+ it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf')}
+ it { should contain_file('/etc/openvpn/test_server/keys').with(
+ 'ensure' => 'link',
+ 'target' => '/etc/openvpn/test_server/easy-rsa/keys'
+ )}
+
+ it { should contain_concat__fragment('openvpn.default.autostart.test_server').with(
+ 'content' => "AUTOSTART=\"$AUTOSTART test_server\"\n",
+ 'target' => '/etc/default/openvpn'
+ )}
+
+ # Execs to working with certificates
+ it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with(
+ 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa'
+ )}
+ it { should contain_exec('generate dh param test_server') }
+ it { should contain_exec('initca test_server') }
+ it { should contain_exec('generate server cert test_server') }
+
+ # Options that should be set
+ it { should contain_openvpn__option('client-config-dir test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'client-config-dir',
+ 'value' => '/etc/openvpn/test_server/client-configs'
+ )}
+ it { should contain_openvpn__option('mode test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'mode',
+ 'value' => 'server'
+ )}
+ it { should contain_openvpn__option('ca test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'ca',
+ 'value' => '/etc/openvpn/test_server/keys/ca.crt'
+ )}
+ it { should contain_openvpn__option('cert test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'cert',
+ 'value' => '/etc/openvpn/test_server/keys/server.crt'
+ )}
+ it { should contain_openvpn__option('key test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'key',
+ 'value' => '/etc/openvpn/test_server/keys/server.key'
+ )}
+ it { should contain_openvpn__option('dh test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'dh',
+ 'value' => '/etc/openvpn/test_server/keys/dh1024.pem'
+ )}
+ it { should contain_openvpn__option('proto test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'proto',
+ 'value' => 'tcp'
+ )}
+ it { should contain_openvpn__option('comp-lzo test_server').with(
+ 'server' => 'test_server',
+ 'key' => 'comp-lzo'
+ )}
+
+ context "when RedHat based machine" do
+ let(:facts) { { :osfamily => 'RedHat', :concat_basedir => '/var/lib/puppet/concat' } }
+
+ it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with(
+ 'ensure' => 'link',
+ 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf'
+ )}
+
+ it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with(
+ 'command' => '/bin/cp -r /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa'
+ )}
+
+ end
+
+ context "when Debian based machine" do
+ let(:facts) { { :osfamily => 'Debian', :concat_basedir => '/var/lib/puppet/concat' } }
+
+ it { should contain_file('/etc/openvpn/test_server/easy-rsa/openssl.cnf').with(
+ 'ensure' => 'link',
+ 'target' => '/etc/openvpn/test_server/easy-rsa/openssl-1.0.0.cnf'
+ )}
+
+ it { should contain_exec('copy easy-rsa to openvpn config folder test_server').with(
+ 'command' => '/bin/cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/test_server/easy-rsa'
+ )}
+
+ end
+
+end
diff --git a/puppet/modules/openvpn/spec/spec_helper.rb b/puppet/modules/openvpn/spec/spec_helper.rb
new file mode 100644
index 00000000..dc7e9f4a
--- /dev/null
+++ b/puppet/modules/openvpn/spec/spec_helper.rb
@@ -0,0 +1,2 @@
+require 'rubygems'
+require 'puppetlabs_spec_helper/module_spec_helper'
diff --git a/puppet/modules/openvpn/templates/etc-default-openvpn.erb b/puppet/modules/openvpn/templates/etc-default-openvpn.erb
new file mode 100644
index 00000000..310e462e
--- /dev/null
+++ b/puppet/modules/openvpn/templates/etc-default-openvpn.erb
@@ -0,0 +1,20 @@
+# This is the configuration file for /etc/init.d/openvpn
+
+#
+# Start only these VPNs automatically via init script.
+# Allowed values are "all", "none" or space separated list of
+# names of the VPNs. If empty, "all" is assumed.
+#
+#AUTOSTART="all"
+#AUTOSTART="none"
+#AUTOSTART="home office"
+#
+# Refresh interval (in seconds) of default status files
+# located in /var/run/openvpn.$NAME.status
+# Defaults to 10, 0 disables status file generation
+#
+#STATUSREFRESH=10
+#STATUSREFRESH=0
+# Optional arguments to openvpn's command line
+OPTARGS=""
+AUTOSTART=""
diff --git a/puppet/modules/openvpn/templates/vars.erb b/puppet/modules/openvpn/templates/vars.erb
new file mode 100644
index 00000000..de988f45
--- /dev/null
+++ b/puppet/modules/openvpn/templates/vars.erb
@@ -0,0 +1,69 @@
+# easy-rsa parameter settings
+
+# NOTE: If you installed from an RPM,
+# don't edit this file in place in
+# /usr/share/openvpn/easy-rsa --
+# instead, you should copy the whole
+# easy-rsa directory to another location
+# (such as /etc/openvpn) so that your
+# edits will not be wiped out by a future
+# OpenVPN package upgrade.
+
+# This variable should point to
+# the top level of the easy-rsa
+# tree.
+export EASY_RSA="/etc/openvpn/<%= name %>/easy-rsa"
+
+#
+# This variable should point to
+# the requested executables
+#
+export OPENSSL="openssl"
+export PKCS11TOOL="pkcs11-tool"
+export GREP="grep"
+
+
+# This variable should point to
+# the openssl.cnf file included
+# with easy-rsa.
+export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
+
+# Edit this variable to point to
+# your soon-to-be-created key
+# directory.
+#
+# WARNING: clean-all will do
+# a rm -rf on this directory
+# so make sure you define
+# it correctly!
+export KEY_DIR="$EASY_RSA/keys"
+
+# Issue rm -rf warning
+echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
+
+# PKCS11 fixes
+export PKCS11_MODULE_PATH="dummy"
+export PKCS11_PIN="dummy"
+
+# Increase this to 2048 if you
+# are paranoid. This will slow
+# down TLS negotiation performance
+# as well as the one-time DH parms
+# generation process.
+export KEY_SIZE=1024
+
+# In how many days should the root CA key expire?
+export CA_EXPIRE=3650
+
+# In how many days should certificates expire?
+export KEY_EXPIRE=3650
+
+# These are the default values for fields
+# which will be placed in the certificate.
+# Don't leave any of these fields blank.
+export KEY_COUNTRY="<%= country %>"
+export KEY_PROVINCE="<%= province %>"
+export KEY_CITY="<%= city %>"
+export KEY_ORG="<%= organization %>"
+export KEY_EMAIL="<%= email %>"
+