update module to make it work with all the new features of trocla 0.2.2
authormh <mh@immerda.ch>
Wed, 27 Jan 2016 23:55:26 +0000 (00:55 +0100)
committermh <mh@immerda.ch>
Wed, 27 Jan 2016 23:55:26 +0000 (00:55 +0100)
21 files changed:
.gitignore
.travis.yml [new file with mode: 0644]
Gemfile [new file with mode: 0644]
README.md
Rakefile [new file with mode: 0644]
manifests/ca/params.pp [new file with mode: 0644]
manifests/config.pp
manifests/master.pp
manifests/master/hiera.pp [new file with mode: 0644]
manifests/master/ree.pp [deleted file]
manifests/params.pp [new file with mode: 0644]
manifests/yaml.pp
metadata.json
spec/classes/ca_params_spec.rb [new file with mode: 0644]
spec/classes/config_spec.rb [new file with mode: 0644]
spec/classes/master_hiera_spec.rb [new file with mode: 0644]
spec/classes/master_spec.rb [new file with mode: 0644]
spec/classes/params_spec.pp [new file with mode: 0644]
spec/classes/yaml_spec.rb [new file with mode: 0644]
spec/spec_helper.rb [new file with mode: 0644]
templates/troclarc.yaml.erb

index 01d0a08..493131d 100644 (file)
@@ -1 +1,4 @@
-pkg/
+spec/fixtures
+.librarian
+.tmp
+*.lock
diff --git a/.travis.yml b/.travis.yml
new file mode 100644 (file)
index 0000000..c85bde4
--- /dev/null
@@ -0,0 +1,15 @@
+rvm:
+  - 1.8.7
+  - 1.9.3
+  - 2.0.0
+script: 'bundle exec rake spec'
+env:
+  - PUPPET_VERSION=3.8.4
+matrix:
+  exclude:
+    # No support for Ruby 2.0 before Puppet 3.2
+    - rvm: 2.0.0
+      env: PUPPET_VERSION=3.0.0
+    - rvm: 2.0.0
+      env: PUPPET_VERSION=3.1.0
+
diff --git a/Gemfile b/Gemfile
new file mode 100644 (file)
index 0000000..71032cf
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,23 @@
+source 'https://rubygems.org'
+
+if ENV.key?('PUPPET_VERSION')
+  puppetversion = "~> #{ENV['PUPPET_VERSION']}"
+else
+  puppetversion = ['>= 3.8.4']
+end
+
+if RUBY_VERSION == '1.8.7'
+  puppetversion = ['~> 3.8.4']
+  gem 'i18n', '~> 0.6.11'
+  gem 'activesupport', '~> 3.2'
+  gem 'highline', '~> 1.6.21'
+  gem 'librarian-puppet', '~> 1.0.0'
+  gem 'rspec', '~> 3.1.0'
+else
+  gem 'librarian-puppet'
+end
+
+gem 'puppet', puppetversion
+gem 'puppet-lint'
+gem 'puppetlabs_spec_helper'
+gem 'rake'
index 551de54..8874f63 100644 (file)
--- a/README.md
+++ b/README.md
@@ -11,6 +11,10 @@ clients if you do not want to use trocla on the clients itself.
 If you want to do your own very custom setup, you should look into the other
 classes.
 
+## Compatibility
+
+* Version 0.2.2 of this module is for version 0.2.2 of trocla.
+
 ## Functions
 
 ### trocla
@@ -85,6 +89,8 @@ trocla, it will just install the necessary packages.
 
 Trocla can also be integrated into [Hiera](https://docs.puppetlabs.com/hiera/) by using ZeroPointEnergy's [hiera-backend](https://github.com/ZeroPointEnergy/hiera-backend-trocla).
 
+Simply `include trocla::master::hiera` to make that backend available.
+
 ## Moar
 
 RTFC and for more information about trocla visit: https://github.com/duritong/trocla
diff --git a/Rakefile b/Rakefile
new file mode 100644 (file)
index 0000000..e5103dd
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,23 @@
+require 'bundler'
+Bundler.require(:rake)
+
+require 'puppetlabs_spec_helper/rake_tasks'
+require 'puppet-lint/tasks/puppet-lint'
+
+PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "vendor/**/*.pp"]
+PuppetLint.configuration.log_format = '%{path}:%{linenumber}:%{KIND}: %{message}'
+PuppetLint.configuration.send("disable_class_inherits_from_params_class")
+
+# use librarian-puppet to manage fixtures instead of .fixtures.yml
+# offers more possibilities like explicit version management, forge downloads,...
+task :librarian_spec_prep do
+  sh "librarian-puppet install --path=spec/fixtures/modules/"
+  pwd = `pwd`.strip
+  unless File.directory?("#{pwd}/spec/fixtures/modules/trocla")
+    sh "ln -s #{pwd} #{pwd}/spec/fixtures/modules/trocla"
+  end
+end
+task :spec_prep => :librarian_spec_prep
+
+
+task :default => [:spec, :lint]
diff --git a/manifests/ca/params.pp b/manifests/ca/params.pp
new file mode 100644 (file)
index 0000000..bb61248
--- /dev/null
@@ -0,0 +1,11 @@
+# input for a ca from trocla, so that you need only
+#
+# trocla('some_ca','x509',$trocla::ca::params::ca_options)
+class trocla::ca::params(
+  $trocla_options = {
+    'profiles' => ['sysdomain_nc','x509long'],
+    'CN'       => "automated-ca ${name} for ${::domain}",
+  },
+) {
+  $ca_options = merge($trocla_options,{ become_ca => true, render => { certonly => true }})
+}
index 7b23a3e..8c52db7 100644 (file)
@@ -1,35 +1,55 @@
 #Installs configuration files for the trocla agent/CLI
 #
 #Options
-# [*adapter*]            Defines the adapter type to use for trocla agent.
-#                        By default it's YAML
-# [*adapter_options*]    This will contain a hash of the adapter options to pass the
-#                        trocla configuration.
-# [*encryption*]         Defines the encryption method for password stored in the backend.
-#                        By default no encryption is used.
-# [*ssl_options*]        This will contain a hash of the ssl options to pass the
-#                        trocla configuration.
-# [*password_length*]    Define the length of default passwords to create. 16 by default
-# [*random_passwords*]   Should trocla generate random passwords
-#                        if none can be found. *true* by default.
-# [*manage_dependencies*] Whether to manage the dependencies or not. Default *true*
+# [*options*]             Options for trocla. Default: empty hash.
+# [*profiles*]            Profiles for trocla. Default: empty hash.
+# [*x509_profile_domain_constraint*]
+#                         A profile for x509 name constraint that matches
+#                         the own domain by default.
+#                         This will add a profile for x509 certs with the
+#                         option 'name_constraints' set to this array of
+#                         domains.
+# [*store*]               Defines the store to be used for trocla. By default
+#                         it's not set, meaning trocla's default (moneta) will
+#                         be used.
+# [*store_options*]       This will contain a hash of the options to pass the
+#                         trocla store configuration.
+# [*encryption*]          Defines the encryption method for password stored in
+#                         the backend. By default it's not set, meaning trocla's
+#                         default (none) will be used.
+# [*encryption_options*]  This will contain a hash of the options for the
+#                         encryption. Default: empty Hash
+# [*manage_dependencies*] Whether to manage the dependencies or not.
+#                         Default *true*
 class trocla::config (
-  $adapter            = 'YAML',
-  $password_length      = 16,
-  $random_passwords     = true,
-  $adapter_options      = {},
-  $encryption           = undef,
-  $ssl_options          = {},
-  $manage_dependencies  = true,
+  $options                         = {},
+  $profiles                        = {},
+  $x509_profile_domain_constraints = [$::domain],
+  $store                           = undef,
+  $store_options                   = {},
+  $encryption                      = undef,
+  $encryption_options              = {},
+  $manage_dependencies             = true,
 ) {
+  include ::trocla::params
   if $manage_dependencies {
-    require trocla::master
+    require ::trocla::master
+  }
+
+  if empty($x509_profile_domain_constraints) {
+    $merged_profiles = $profiles
+  } else {
+    $default_profiles = {
+      "${trocla::params::sysdomain_profile_name}" => {
+        name_constraints => $x509_profile_domain_constraints
+      }
+    }
+    $merged_profiles = merge($default_profiles,$profiles)
   }
 
   # Deploy default config file and link it for trocla cli lookup
   file{
     "${settings::confdir}/troclarc.yaml":
-      ensure  => present,
       content => template('trocla/troclarc.yaml.erb'),
       owner   => root,
       group   => puppet,
@@ -38,5 +58,4 @@ class trocla::config (
       ensure => link,
       target => "${settings::confdir}/troclarc.yaml";
   }
-
 }
index ad47914..43e203d 100644 (file)
@@ -3,15 +3,18 @@
 # This module manages the necessary things for trocla on a master.
 #
 class trocla::master (
-  $provider     = gem,
+  $provider = 'default',
 ) {
-  #Main trocla install
   package {'trocla':
-    ensure   => present,
-    provider => $provider,
+    ensure   => 'installed',
   }
 
-  if $provider != 'gem' {
+  if $provider != 'default' {
+    Package['trocla']{
+      provider => $provider,
+    }
+  }
+  if $provider != 'gem' and $::osfamily == 'RedHat' {
     Package['trocla']{
       name => 'rubygem-trocla'
     }
diff --git a/manifests/master/hiera.pp b/manifests/master/hiera.pp
new file mode 100644 (file)
index 0000000..75b8bb3
--- /dev/null
@@ -0,0 +1,6 @@
+# manage trocla/hiera integration
+class trocla::master::hiera {
+  package{'rubygem-hiera-backend-trocla':
+    ensure => present,
+  }
+}
diff --git a/manifests/master/ree.pp b/manifests/master/ree.pp
deleted file mode 100644 (file)
index bf2c400..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# Class: trocla::master::ree
-#
-# This module manages the necessary things for trocla on a master for
-# RubyEnterprise installation.
-#
-# [Remember: No empty lines between comments and class definition]
-class trocla::master::ree {
-
-  require ruby_enterprise::gems::moneta
-  require ruby_enterprise::gems::highline
-
-  ruby_enterprise::gem{'trocla': }
-}
diff --git a/manifests/params.pp b/manifests/params.pp
new file mode 100644 (file)
index 0000000..f99aa2a
--- /dev/null
@@ -0,0 +1,6 @@
+# a set of default params for various trocla usages
+class trocla::params(
+  $sysdomain_profile_name = 'sysdomain_nc'
+){
+
+}
index dc20c2e..8ac0071 100644 (file)
@@ -2,24 +2,20 @@
 # This will install and configure trocla with the
 # default yaml storage.
 #
-# [*password_length*]  The default length of new passwords: 16
-# [*random_passwords*] Whether trocla should generate random
-#                      passwords or not. Default: true
 # [*data_file*]        Where to store the passwords.
-#                      Default: {$settings::server_datadir}/trocla_data.yaml"
-#                      This will likely be: /var/lib/puppet/server_data/trocla_data.yaml
+#                      Default: /var/lib/trocla/trocla_data.yaml
+#                      This should be managed using the package.
 class trocla::yaml(
-  $password_length  = 16,
-  $random_passwords = true,
-  $data_file        = "${settings::server_datadir}/trocla_data.yaml",
+  $data_file = '/var/lib/trocla/trocla_data.yaml',
 ) {
 
   class{'trocla::config':
-    password_length   => $password_length,
-    random_passwords  => $random_passwords,
-    adapter           => 'YAML',
-    adapter_options   => {
-      file => $data_file,
+    store         => 'moneta',
+    store_options => {
+      adapter         => 'YAML',
+      adapter_options => {
+        file => $data_file,
+      },
     },
   }
 
index af2d50b..a5b7d9a 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "duritong-trocla",
-  "version": "0.0.8",
+  "version": "0.2.2",
   "author": "duritong",
   "summary": "This modules allows you to use trocla (https://github.com/duritong/trocla) from puppet.",
   "license": "GPLv2",
@@ -9,6 +9,6 @@
   "issues_url": "https://github.com/duritong/puppet-trocla/issues",
   "description": "This modules allows you use trocla lookups as puppet functions.",
   "dependencies": [
-  
+    {"name":"puppetlabs/stdlib","version_requirement":">= 3.2.0"}
   ]
 }
diff --git a/spec/classes/ca_params_spec.rb b/spec/classes/ca_params_spec.rb
new file mode 100644 (file)
index 0000000..5277972
--- /dev/null
@@ -0,0 +1,8 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::ca::params', :type => 'class' do
+  context 'with default params' do
+    it { should compile.with_all_deps }
+  end
+end
+
diff --git a/spec/classes/config_spec.rb b/spec/classes/config_spec.rb
new file mode 100644 (file)
index 0000000..fc0a33a
--- /dev/null
@@ -0,0 +1,114 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::config', :type => 'class' do
+  let(:facts){
+    {
+      :domain => 'example.com',
+    }
+  }
+  context 'with default params' do
+    it { should contain_class('trocla::params') }
+    it { should contain_class('trocla::master') }
+    it { should contain_file('/etc/puppet/troclarc.yaml').with(
+      :owner => 'root',
+      :group => 'puppet',
+      :mode  => '0640'
+    )}
+    it { should contain_file('/etc/puppet/troclarc.yaml').with_content("---
+profiles:
+  sysdomain_nc:
+    name_constraints:
+    - example.com
+") }
+    it { should contain_file('/etc/troclarc.yaml').with(
+      :ensure => 'link',
+      :target => '/etc/puppet/troclarc.yaml'
+    )}
+
+    it { should compile.with_all_deps }
+  end
+
+  context 'with other params' do
+    let(:params) {
+      {
+        :options => {
+          'length'   => 24,
+          'profiles' => 'mydefaultprofile',
+          'random'   => false,
+          'expires'  => 60*60*24, #1day
+        },
+        :profiles => {
+          'mydefaultprofile' => {
+            'length' => 20,
+          },
+          'anotherprofile' => {
+            'random' => true,
+            'expires' => false,
+          },
+        },
+        :x509_profile_domain_constraints => ['domain1.com','domain2.com'],
+        :store => 'moneta',
+        :store_options => {
+          'adapter' => 'Sequel',
+          'adapter_options' => {
+            'db'       => 'mysql://db.server.name',
+            'user'     => 'trocla',
+            'password' => 'secret_password',
+            'database' => 'trocladb',
+            'table'    => 'trocla',
+          },
+        },
+        :encryption => 'ssl',
+        :encryption_options => {
+          'private_key' => '/var/lib/puppet/ssl/private_keys/trocla.pem',
+          'public_key'  => '/var/lib/puppet/ssl/public_keys/trocla.pem',
+        },
+        :manage_dependencies => false,
+      }
+    }
+    it { should contain_class('trocla::params') }
+    it { should_not contain_class('trocla::master') }
+    it { should contain_file('/etc/puppet/troclarc.yaml').with(
+      :owner => 'root',
+      :group => 'puppet',
+      :mode  => '0640'
+    )}
+    it { should contain_file('/etc/puppet/troclarc.yaml').with_content("---
+encryption: :ssl
+encryption_options:
+  :private_key: /var/lib/puppet/ssl/private_keys/trocla.pem
+  :public_key: /var/lib/puppet/ssl/public_keys/trocla.pem
+options:
+  expires: 86400
+  length: 24
+  profiles: mydefaultprofile
+  random: false
+profiles:
+  anotherprofile:
+    expires: false
+    random: true
+  mydefaultprofile:
+    length: 20
+  sysdomain_nc:
+    name_constraints:
+    - domain1.com
+    - domain2.com
+store: :moneta
+store_options:
+  adapter: :Sequel
+  adapter_options:
+    :database: trocladb
+    :db: mysql://db.server.name
+    :password: secret_password
+    :table: trocla
+    :user: trocla
+") }
+    it { should contain_file('/etc/troclarc.yaml').with(
+      :ensure => 'link',
+      :target => '/etc/puppet/troclarc.yaml'
+    )}
+
+    it { should compile.with_all_deps }
+  end
+end
+
diff --git a/spec/classes/master_hiera_spec.rb b/spec/classes/master_hiera_spec.rb
new file mode 100644 (file)
index 0000000..62112fb
--- /dev/null
@@ -0,0 +1,11 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::master::hiera', :type => 'class' do
+  context 'with default params' do
+    it { should compile.with_all_deps }
+    it { should contain_package('rubygem-hiera-backend-trocla').with(
+      :ensure => 'present',
+    )}
+  end
+end
+
diff --git a/spec/classes/master_spec.rb b/spec/classes/master_spec.rb
new file mode 100644 (file)
index 0000000..ad99c86
--- /dev/null
@@ -0,0 +1,52 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::master', :type => 'class' do
+  context 'with default params' do
+    context 'on RedHat' do
+      let(:facts) {
+        {
+          :osfamily => 'RedHat',
+        }
+      }
+      it { should contain_package('trocla').with(
+        :name     => 'rubygem-trocla',
+        :ensure   => 'installed'
+      )}
+      it { should compile.with_all_deps }
+    end
+    context 'on Debian' do
+      let(:facts) {
+        {
+          :osfamily => 'Debian',
+        }
+      }
+      it { should contain_package('trocla').with(
+        :ensure   => 'installed'
+      )}
+      it { should compile.with_all_deps }
+    end
+  end
+  context 'with gem provider' do
+    let(:params){
+      {
+        :provider => 'gem'
+      }
+    }
+    it { should contain_package('trocla').with(
+      :ensure   => 'installed',
+      :provider => 'gem'
+    )}
+
+    it { should compile.with_all_deps }
+    context 'on RedHat' do
+      it { should contain_package('trocla').with(
+        :name     => 'trocla',
+        :ensure   => 'installed',
+        :provider => 'gem'
+      )}
+
+      it { should compile.with_all_deps }
+    end
+  end
+end
+
diff --git a/spec/classes/params_spec.pp b/spec/classes/params_spec.pp
new file mode 100644 (file)
index 0000000..4d05e1f
--- /dev/null
@@ -0,0 +1,8 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::params', :type => 'class' do
+  context 'with default params' do
+    it { should compile.with_all_deps }
+  end
+end
+
diff --git a/spec/classes/yaml_spec.rb b/spec/classes/yaml_spec.rb
new file mode 100644 (file)
index 0000000..c5912f2
--- /dev/null
@@ -0,0 +1,39 @@
+require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
+
+describe 'trocla::yaml', :type => 'class' do
+  let(:facts){
+    {
+      :domain => 'example.com',
+    }
+  }
+  context 'with default params' do
+    it { should contain_class('trocla::config').with(
+      'store' => 'moneta',
+      'store_options' => {
+        'adapter' => 'YAML',
+        'adapter_options' => {
+          'file' => '/var/lib/trocla/trocla_data.yaml',
+        }
+      }
+    )}
+    it { should contain_file('/etc/puppet/troclarc.yaml').with_content("---
+profiles:
+  sysdomain_nc:
+    name_constraints:
+    - example.com
+store: :moneta
+store_options:
+  adapter: :YAML
+  adapter_options:
+    :file: /var/lib/trocla/trocla_data.yaml
+") }
+    it { should contain_file('/var/lib/trocla/trocla_data.yaml').with(
+      :ensure => 'file',
+      :owner  => 'puppet',
+      :group  => 0,
+      :mode   => '0600'
+    )}
+    it { should compile.with_all_deps }
+  end
+end
+
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644 (file)
index 0000000..381f972
--- /dev/null
@@ -0,0 +1,13 @@
+require 'puppetlabs_spec_helper/module_spec_helper'
+require 'rake'
+
+fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))
+
+RSpec.configure do |c|
+  c.module_path = File.join(fixture_path, 'modules')
+  c.manifest_dir = File.join(fixture_path, 'manifests')
+  c.pattern = FileList[c.pattern].exclude(/^spec\/fixtures/)
+end
+
+Puppet::Util::Log.level = :warning
+Puppet::Util::Log.newdestination(:console)
index cd4da3d..5584fd8 100644 (file)
@@ -1,20 +1,44 @@
----
-options:
-    random: <%= @random_passwords %>
-    length: <%= @password_length %> 
-adapter: :<%= @adapter %>
-<% unless @adapter_options.empty? %>
-adapter_options:
-<% @adapter_options.keys.sort.each do |key| -%>
-    :<%= key %>: '<%= @adapter_options[key] %>'
-<% end -%>
-<% end -%>
-<% if @encryption %>
-encryption: :<%= @encryption %>
-<% end -%>
-<% unless @ssl_options.empty? %>
-ssl_options:
-<% @ssl_options.keys.sort.each do |key| -%>
-    :<%= key %>: '<%= @ssl_options[key] %>'
-<% end -%>
+<%
+  # stupid but effective sorting of yaml
+  # forgive me for that, but puppet monkeypatches yaml heavily and breaks it constantly
+  # for our use case it should be sufficient, otherwise we need to
+  # extent it to address the new problems
+  def sort_pseudo_yaml(obj, indent='')
+    arr = obj.sort {|a,b| (a[0].is_a?(Symbol) ? a[0].to_s : a[0]) <=> (b[0].is_a?(Symbol) ? b[0].to_s : b[0]) }
+    out = []
+    arr.each do |e|
+      if e[1].is_a?(Hash)
+        out << "#{indent}#{e[0]}:"
+        out << sort_pseudo_yaml(e[1],indent+'  ')
+      elsif e[1].is_a?(Array)
+        out << (["#{indent}#{e[0]}:"]+e[1].collect{|e| "- #{e}" }).join("\n#{indent}")
+      else
+        out << "#{indent}#{e[0].is_a?(Symbol) ? ":#{e[0].to_s}" : e[0]}: #{e[1].is_a?(Symbol) ? ":#{e[1].to_s}" : e[1]}"
+      end
+    end
+    out.join("\n")
+  end
+  def sym_keys(h)
+    h.keys.inject({}) do |r,k|
+      r[k.to_sym] = h[k]
+      r
+    end
+  end
+  # transform special options so they are understood by the other libraries
+  so = @store_options.dup
+  so['adapter'] = so['adapter'].to_sym if so['adapter']
+  so['adapter_options'] = sym_keys(so['adapter_options']) if so['adapter_options']
+  eo = @encryption_options ? sym_keys(@encryption_options) : {}
+  options_hash = {
+    'store'              => @store.nil? ? @store : @store.to_sym,
+    'store_options'      => so,
+    'encryption'         => @encryption.nil? ? @encryption : @encryption.to_sym,
+    'encryption_options' => eo,
+    'options'            => @options,
+    'profiles'           => @merged_profiles,
+  }.delete_if{|k,v| v.nil? || (v.is_a?(Symbol) ? v.to_s : v).empty? }
+  output = sort_pseudo_yaml(options_hash)
+-%>---
+<% unless output.empty? -%>
+<%= output %>
 <% end -%>