classes:
stdlib: ~
+base_installation::ldap_base: "dc=immae,dc=eu"
+base_installation::ldap_dn: "cn=%{facts.ec2_metadata.hostname},ou=hosts,dc=immae,dc=eu"
+base_installation::ldap_cn: "%{facts.ec2_metadata.hostname}"
+base_installation::ldap_server: "ldap.immae.eu"
+base_installation::ldap_uri: "ldaps://ldap.immae.eu"
+base_installation::puppet_conf_path: "/etc/puppetlabs/puppet"
base_installation::puppet_code_path: "/etc/puppetlabs/code"
+base_installation::puppet_pass_seed: "/etc/puppetlabs/puppet/password_seed"
+base_installation::puppet_ssl_path: "/etc/puppetlabs/ssl"
base_installation::system_locales: ["fr_FR.UTF-8", "en_US.UTF-8"]
base_installation::system_timezone: "Europe/Paris"
base_installation::system_users:
base_installation:
stage: "setup"
-base_installation::system_hostname: "new.immae.eu"
base_installation::grub_device: "/dev/sdb"
+base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt"
+base_installation::system_hostname: "new.immae.eu"
--- /dev/null
+module Puppet::Parser::Functions
+ newfunction(:generate_password, :type => :rvalue, :doc => <<-EOS
+Returns a semi-random string based on a seed and a value. Will always generate the same value with the same entry.
+Prototype:
+ generate_password(length, seed_file, password_key)
+EOS
+) do |*arguments|
+ arguments = arguments.shift if arguments.first.is_a?(Array)
+
+ raise Puppet::ParseError, "generate_password(): Wrong number of arguments " +
+ "given (#{arguments.size} for 3)" if arguments.size != 3
+
+ size = arguments.shift
+ seed_file = arguments.shift
+ password_key = arguments.shift
+
+ unless size.class.ancestors.include?(Numeric) or size.is_a?(String)
+ raise Puppet::ParseError, 'generate_password(): Requires a numeric first argument'
+ end
+
+ size = size.to_i
+
+ set = ('a' .. 'z').to_a + ('A' .. 'Z').to_a + ('0' .. '9').to_a
+
+ key = "#{File.open(seed_file).read}:#{password_key}"
+
+ size.times.collect do |i|
+ set[OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, i.to_s).to_i(16) % set.size]
+ end.join
+end
+end
--- /dev/null
+#
+# Simple module for logging messages on the client-side
+
+
+module Puppet
+ Type.newtype(:notify_refresh) do
+ @doc = "Sends an arbitrary message to the agent run-time log."
+
+ apply_to_all
+
+ newproperty(:message, :idempotent => false) do
+ desc "The message to be sent to the log."
+ def sync(refreshing = false)
+ if refreshing || !@resource.refreshonly?
+ Puppet.send(@resource[:loglevel], self.should)
+ end
+ return
+ end
+
+ def retrieve
+ :absent
+ end
+
+ def insync?(is)
+ true
+ end
+
+ defaultto { @resource[:name] }
+ end
+
+ def refresh
+ self.property(:message).sync(true)
+ end
+
+ newparam(:name) do
+ desc "An arbitrary tag for your own reference; the name of the message."
+ isnamevar
+ end
+
+ newparam(:refreshonly, :boolean => true, :parent => Puppet::Parameter::Boolean) do
+ defaultto false
+ end
+
+ end
+end
class base_installation (
Optional[String] $grub_device = $base_installation::params::grub_device,
+ Optional[String] $ldap_base = $base_installation::params::ldap_base,
+ Optional[String] $ldap_cert_path = $base_installation::params::ldap_cert_path,
+ Optional[String] $ldap_cn = $base_installation::params::ldap_cn,
+ Optional[String] $ldap_dn = $base_installation::params::ldap_dn,
+ Optional[String] $ldap_server = $base_installation::params::ldap_server,
+ Optional[String] $ldap_uri = $base_installation::params::ldap_uri,
Optional[String] $puppet_code_path = $base_installation::params::puppet_code_path,
+ Optional[String] $puppet_conf_path = $base_installation::params::puppet_conf_path,
+ Optional[String] $puppet_pass_seed = $base_installation::params::puppet_pass_seed,
+ Optional[String] $puppet_ssl_path = $base_installation::params::puppet_ssl_path,
Optional[String] $system_hostname = $base_installation::params::system_hostname,
Optional[Array[String]] $system_locales = $base_installation::params::system_locales,
Optional[String] $system_timezone = $base_installation::params::system_timezone,
contain ::base_installation::logs
contain ::base_installation::cronie
contain ::base_installation::ssh
+ contain ::base_installation::ldap
contain ::base_installation::services
contain ::base_installation::users
contain ::base_installation::package_managers
+ contain ::base_installation::puppet
}
--- /dev/null
+class base_installation::ldap inherits base_installation {
+ ensure_packages(["openldap"])
+
+ File {
+ mode => "0644",
+ owner => "root",
+ group => "root",
+ }
+
+ file { '/etc/openldap':
+ ensure => directory,
+ require => Package["openldap"],
+ recurse => true,
+ purge => true,
+ force => true,
+ }
+
+ file { '/etc/openldap/ldap.conf':
+ ensure => present,
+ content => template("base_installation/ldap/ldap.conf.erb"),
+ require => File['/etc/openldap'],
+ }
+
+}
class base_installation::params {
$puppet_code_path = "/etc/puppetlabs/code"
+ $puppet_conf_path = "/etc/puppetlabs/puppet"
+ $puppet_pass_seed = "/etc/puppetlabs/puppet/password_seed"
+ $puppet_ssl_path = "/etc/puppetlabs/ssl"
$grub_device = "/dev/sda"
+ $ldap_base = "dc=example,dc=com"
+ $ldap_cn = "node"
+ $ldap_dn = "cn=node,ou=hosts,dc=example,dc=com"
+ $ldap_cert_path = "/etc/ssl/certs/ca-certificates.crt"
+ $ldap_uri = "ldaps://ldap.example.com"
+ $ldap_server = "ldap.example.com"
$system_hostname = "example.com"
$system_locales = ["en_US.UTF-8"]
$system_timezone = "UTC"
--- /dev/null
+class base_installation::puppet (
+ $password_seed = $base_installation::puppet_pass_seed
+) inherits base_installation {
+ File {
+ mode => "0600",
+ owner => "root",
+ group => "root",
+ }
+
+ exec { 'generate_password_seed':
+ command => "/usr/bin/openssl rand -base64 -out $password_seed 256",
+ creates => $password_seed,
+ environment => "RANDFILE=/dev/null",
+ }
+
+ unless empty(find_file($password_seed)) {
+ $ldap_password = generate_password(24, $password_seed, "ldap")
+ $ssha_ldap_seed = generate_password(5, $password_seed, "ldap_seed")
+
+ package { 'gem:ruby-ldap':
+ name => "ruby-ldap",
+ ensure => present,
+ provider => "gem",
+ install_options => "--no-user-install"
+ }
+
+ file { $password_seed:
+ mode => "0600",
+ }
+
+ file { $base_installation::puppet_conf_path:
+ ensure => directory,
+ require => [Package["puppet"], Package["gem:ruby-ldap"]],
+ recurse => true,
+ purge => true,
+ force => true,
+ }
+
+ file { "$base_installation::puppet_conf_path/puppet.conf":
+ content => template("base_installation/puppet/puppet.conf.erb"),
+ require => File[$base_installation::puppet_conf_path],
+ }
+
+ file { "$base_installation::puppet_conf_path/host_ldap.info":
+ content => template("base_installation/puppet/host_ldap.info.erb"),
+ require => File[$base_installation::puppet_conf_path],
+ notify => Notify_refresh["notify-ldap-password"],
+ }
+
+ notify_refresh { "notify-ldap-password":
+ message => template("base_installation/puppet/host_ldap.info.erb"),
+ refreshonly => true
+ }
+ }
+}
--- /dev/null
+uri <%= @ldap_uri %>
+base <%= @ldap_base %>
+tls_cacert <%= @ldap_cert_path %>
--- /dev/null
+#### Please add this node to LDAP:
+ldapadd -D "cn=root,<%= @ldap_base %>" -W << 'EOF'
+dn: <%= @ldap_dn %>
+cn: <%= @ldap_cn %>
+objectclass: device
+objectclass: top
+objectclass: simpleSecurityObject
+objectclass: puppetClient
+userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %>
+EOF
+#### Or modify an existing entry:
+ldapmodify -D "cn=root,<%= @ldap_base %>" -W << 'EOF'
+dn: <%= @ldap_dn %>
+changetype: modify
+replace: userPassword
+userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %>
+EOF
--- /dev/null
+[main]
+ssldir = <%= @puppet_ssl_path %>
+
+node_terminus = ldap
+ldapserver = <%= @ldap_server %>
+ldaptls = true
+ldapbase = <%= @ldap_base %>
+ldapuser = <%= @ldap_dn %>
+ldappassword = <%= @ldap_password %>
+ldapclassattrs = puppetClass
+ldapparentattr = parentNode
+ldapstackedattrs = puppetVar
-Subproject commit 16fd47d7c74e9bf44ec6f6a9197f16e9a3f57092
+Subproject commit e5d624da43c3571e476ddfa4bbfde4acc5800f99