]> git.immae.eu Git - perso/Immae/Projets/Puppet.git/commitdiff
Add LDAP support
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Wed, 30 Aug 2017 20:16:39 +0000 (22:16 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 31 Aug 2017 20:59:53 +0000 (22:59 +0200)
12 files changed:
environments/production/data/common.yaml
environments/production/data/types/vps-ovhssd-1.yaml
modules/base_installation/lib/puppet/parser/functions/generate_password.rb [new file with mode: 0644]
modules/base_installation/lib/puppet/type/notify_refresh.rb [new file with mode: 0644]
modules/base_installation/manifests/init.pp
modules/base_installation/manifests/ldap.pp [new file with mode: 0644]
modules/base_installation/manifests/params.pp
modules/base_installation/manifests/puppet.pp [new file with mode: 0644]
modules/base_installation/templates/ldap/ldap.conf.erb [new file with mode: 0644]
modules/base_installation/templates/puppet/host_ldap.info.erb [new file with mode: 0644]
modules/base_installation/templates/puppet/puppet.conf.erb [new file with mode: 0644]
modules/inifile

index 01bbcac6d26ace5281347e8de7d662c12d503885..32e0aa3c87c8f636af4004aec40ececb53cdd59e 100644 (file)
@@ -2,7 +2,15 @@
 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:
index eb4934b81c49b1aa56876ba15d223432e09706d7..217dd82fc2c7a2109abbb3074a6cae77fdcd6996 100644 (file)
@@ -3,5 +3,6 @@ classes:
   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"
diff --git a/modules/base_installation/lib/puppet/parser/functions/generate_password.rb b/modules/base_installation/lib/puppet/parser/functions/generate_password.rb
new file mode 100644 (file)
index 0000000..384d81b
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/modules/base_installation/lib/puppet/type/notify_refresh.rb b/modules/base_installation/lib/puppet/type/notify_refresh.rb
new file mode 100644 (file)
index 0000000..35f0cda
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# 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
index 65c5178c62d13c41b859e0e325c68b9ee49085b1..f9fdcd47473ed0a3bc7c56d099e26ae3cd475114 100644 (file)
@@ -1,6 +1,15 @@
 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,
@@ -15,7 +24,9 @@ class base_installation (
   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
 }
diff --git a/modules/base_installation/manifests/ldap.pp b/modules/base_installation/manifests/ldap.pp
new file mode 100644 (file)
index 0000000..1825700
--- /dev/null
@@ -0,0 +1,24 @@
+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'],
+  }
+
+}
index f09f01a60ba3cb3075746d423bcf6ec02763b7c4..c03eb1e3585abb2ecf34a0d7410720afdbc8e63b 100644 (file)
@@ -1,6 +1,15 @@
 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"
diff --git a/modules/base_installation/manifests/puppet.pp b/modules/base_installation/manifests/puppet.pp
new file mode 100644 (file)
index 0000000..cd5697a
--- /dev/null
@@ -0,0 +1,55 @@
+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
+    }
+  }
+}
diff --git a/modules/base_installation/templates/ldap/ldap.conf.erb b/modules/base_installation/templates/ldap/ldap.conf.erb
new file mode 100644 (file)
index 0000000..626a986
--- /dev/null
@@ -0,0 +1,3 @@
+uri        <%= @ldap_uri %>
+base       <%= @ldap_base %>
+tls_cacert <%= @ldap_cert_path %>
diff --git a/modules/base_installation/templates/puppet/host_ldap.info.erb b/modules/base_installation/templates/puppet/host_ldap.info.erb
new file mode 100644 (file)
index 0000000..a350c37
--- /dev/null
@@ -0,0 +1,17 @@
+#### 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
diff --git a/modules/base_installation/templates/puppet/puppet.conf.erb b/modules/base_installation/templates/puppet/puppet.conf.erb
new file mode 100644 (file)
index 0000000..99d9fc3
--- /dev/null
@@ -0,0 +1,12 @@
+[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
index 16fd47d7c74e9bf44ec6f6a9197f16e9a3f57092..e5d624da43c3571e476ddfa4bbfde4acc5800f99 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 16fd47d7c74e9bf44ec6f6a9197f16e9a3f57092
+Subproject commit e5d624da43c3571e476ddfa4bbfde4acc5800f99