diff --git a/REFERENCE.md b/REFERENCE.md index f9ce918e..9f75af3b 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -446,6 +446,10 @@ The following parameters are available in the `puppetboard::apache::conf` class: * [`ldap_bind_authoritative`](#-puppetboard--apache--conf--ldap_bind_authoritative) * [`ldap_require_group`](#-puppetboard--apache--conf--ldap_require_group) * [`ldap_require_group_dn`](#-puppetboard--apache--conf--ldap_require_group_dn) +* [`ldap_require_user`](#-puppetboard--apache--conf--ldap_require_user) +* [`ldap_require_dn`](#-puppetboard--apache--conf--ldap_require_dn) +* [`ldap_require_attribute`](#-puppetboard--apache--conf--ldap_require_attribute) +* [`ldap_require_filter`](#-puppetboard--apache--conf--ldap_require_filter) * [`virtualenv_dir`](#-puppetboard--apache--conf--virtualenv_dir) ##### `wsgi_alias` @@ -552,6 +556,38 @@ LDAP group DN for LDAP group Default value: `undef` +##### `ldap_require_user` + +Data type: `Optional[String[1]]` + +if set, list of uids for Require ldap-user directive + +Default value: `undef` + +##### `ldap_require_dn` + +Data type: `Optional[String[1]]` + +if set, dn to be matched by Require ldap-dn directive + +Default value: `undef` + +##### `ldap_require_attribute` + +Data type: `Optional[String[1]]` + +if set, attributes of LDAP users for Require ldap-attribute directive + +Default value: `undef` + +##### `ldap_require_filter` + +Data type: `Optional[String[1]]` + +if set, LDAP search filter for Require ldap-filter directive + +Default value: `undef` + ##### `virtualenv_dir` Data type: `Stdlib::Absolutepath` @@ -588,6 +624,10 @@ The following parameters are available in the `puppetboard::apache::vhost` class * [`ldap_bind_authoritative`](#-puppetboard--apache--vhost--ldap_bind_authoritative) * [`ldap_require_group`](#-puppetboard--apache--vhost--ldap_require_group) * [`ldap_require_group_dn`](#-puppetboard--apache--vhost--ldap_require_group_dn) +* [`ldap_require_user`](#-puppetboard--apache--vhost--ldap_require_user) +* [`ldap_require_dn`](#-puppetboard--apache--vhost--ldap_require_dn) +* [`ldap_require_attribute`](#-puppetboard--apache--vhost--ldap_require_attribute) +* [`ldap_require_filter`](#-puppetboard--apache--vhost--ldap_require_filter) * [`virtualenv_dir`](#-puppetboard--apache--vhost--virtualenv_dir) * [`custom_apache_parameters`](#-puppetboard--apache--vhost--custom_apache_parameters) @@ -749,6 +789,38 @@ LDAP group DN for LDAP group Default value: `undef` +##### `ldap_require_user` + +Data type: `Optional[String[1]]` + +if set, list of uids for Require ldap-user directive + +Default value: `undef` + +##### `ldap_require_dn` + +Data type: `Optional[String[1]]` + +if set, dn to be matched by Require ldap-dn directive + +Default value: `undef` + +##### `ldap_require_attribute` + +Data type: `Optional[String[1]]` + +if set, attributes of LDAP users for Require ldap-attribute directive + +Default value: `undef` + +##### `ldap_require_filter` + +Data type: `Optional[String[1]]` + +if set, LDAP search filter for Require ldap-filter directive + +Default value: `undef` + ##### `virtualenv_dir` Data type: `Stdlib::Absolutepath` diff --git a/manifests/apache/conf.pp b/manifests/apache/conf.pp index 81802f4e..da69fc6a 100644 --- a/manifests/apache/conf.pp +++ b/manifests/apache/conf.pp @@ -13,6 +13,10 @@ # @param ldap_bind_authoritative Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot bind with the credentials # @param ldap_require_group LDAP group to require on login # @param ldap_require_group_dn LDAP group DN for LDAP group +# @param ldap_require_user if set, list of uids for Require ldap-user directive +# @param ldap_require_dn if set, dn to be matched by Require ldap-dn directive +# @param ldap_require_attribute if set, attributes of LDAP users for Require ldap-attribute directive +# @param ldap_require_filter if set, LDAP search filter for Require ldap-filter directive # @param virtualenv_dir Set location where virtualenv will be installed # # @note Make sure you have purge_configs set to false in your apache class! @@ -32,6 +36,10 @@ Optional[String[1]] $ldap_bind_authoritative = undef, Boolean $ldap_require_group = $puppetboard::ldap_require_group, Optional[String[1]] $ldap_require_group_dn = undef, + Optional[String[1]] $ldap_require_user = undef, + Optional[String[1]] $ldap_require_dn = undef, + Optional[String[1]] $ldap_require_attribute = undef, + Optional[String[1]] $ldap_require_filter = undef, Stdlib::Absolutepath $virtualenv_dir = $puppetboard::virtualenv_dir, ) { $wsgi = $facts['os']['family'] ? { @@ -70,6 +78,10 @@ 'ldap_bind_password' => $ldap_bind_password, 'ldap_require_group_dn' => $ldap_require_group_dn, 'ldap_require_group' => $ldap_require_group, + 'ldap_require_user' => $ldap_require_user, + 'ldap_require_dn' => $ldap_require_dn, + 'ldap_require_attribute' => $ldap_require_attribute, + 'ldap_require_filter' => $ldap_require_filter, 'ldap_url' => $ldap_url, 'max_reqs' => $max_reqs, 'threads' => $threads, diff --git a/manifests/apache/vhost.pp b/manifests/apache/vhost.pp index 30672b06..22641410 100644 --- a/manifests/apache/vhost.pp +++ b/manifests/apache/vhost.pp @@ -20,6 +20,10 @@ # @param ldap_bind_authoritative Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot bind with the credentials # @param ldap_require_group LDAP group to require on login # @param ldap_require_group_dn LDAP group DN for LDAP group +# @param ldap_require_user if set, list of uids for Require ldap-user directive +# @param ldap_require_dn if set, dn to be matched by Require ldap-dn directive +# @param ldap_require_attribute if set, attributes of LDAP users for Require ldap-attribute directive +# @param ldap_require_filter if set, LDAP search filter for Require ldap-filter directive # @param virtualenv_dir Set location where virtualenv will be installed # @param custom_apache_parameters A hash passed to the `apache::vhost` for custom settings class puppetboard::apache::vhost ( @@ -43,6 +47,10 @@ Optional[String[1]] $ldap_bind_authoritative = undef, Boolean $ldap_require_group = $puppetboard::ldap_require_group, Optional[String[1]] $ldap_require_group_dn = undef, + Optional[String[1]] $ldap_require_user = undef, + Optional[String[1]] $ldap_require_dn = undef, + Optional[String[1]] $ldap_require_attribute = undef, + Optional[String[1]] $ldap_require_filter = undef, Stdlib::Absolutepath $virtualenv_dir = $puppetboard::virtualenv_dir, Hash $custom_apache_parameters = {}, ) { @@ -94,6 +102,10 @@ 'ldap_bind_password' => $ldap_bind_password, 'ldap_require_group_dn' => $ldap_require_group_dn, 'ldap_require_group' => $ldap_require_group, + 'ldap_require_user' => $ldap_require_user, + 'ldap_require_dn' => $ldap_require_dn, + 'ldap_require_attribute' => $ldap_require_attribute, + 'ldap_require_filter' => $ldap_require_filter, 'ldap_url' => $ldap_url, }, ), diff --git a/spec/acceptance/class_spec.rb b/spec/acceptance/class_spec.rb index 458dc0d7..c41b67e3 100644 --- a/spec/acceptance/class_spec.rb +++ b/spec/acceptance/class_spec.rb @@ -219,4 +219,200 @@ class { 'puppetdb': it { is_expected.to contain "PUPPETDB_CERT = '/var/lib/puppet/ssl/certs/test.networkninjas.net.pem'" } end end + + context 'AUTH ldap-user' do + it 'works with no errors' do + pp = <<-EOS + # Configure Apache on this server + class { 'apache': } + class { 'apache::mod::authnz_ldap': } + -> class { 'puppetboard': + manage_virtualenv => true, + manage_git => true, + puppetdb_host => 'puppet.example.com', + puppetdb_port => 8081, + puppetdb_key => "/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem", + puppetdb_ssl_verify => true, + puppetdb_cert => "/var/lib/puppet/ssl/certs/test.networkninjas.net.pem", + require => Class['puppetdb'], + secret_key => 'this_should_be_a_long_secret_string', + } + class { 'puppetboard::apache::conf': + enable_ldap_auth => true, + ldap_bind_dn => 'cn=user,dc=puppet,dc=example,dc=com', + ldap_bind_password => 'password', + ldap_url => 'ldap://puppet.example.com', + ldap_require_user => 'admin1uid admin2uid', + } + # Configure PuppetDB + class { 'puppetdb': + disable_ssl => true, + manage_firewall => false, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_failures: true) + end + + describe file(apache_conf_file) do + it { is_expected.to contain 'AuthBasicProvider ldap' } + it { is_expected.to contain 'AuthLDAPBindDN "cn=user,dc=puppet,dc=example,dc=com"' } + it { is_expected.to contain 'AuthLDAPURL "ldap://puppet.example.com"' } + it { is_expected.to contain 'Require ldap-user admin1uid admin2uid' } + end + + describe file('/srv/puppetboard/puppetboard/settings.py') do + it { is_expected.to contain "PUPPETDB_KEY = '/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem'" } + it { is_expected.to contain "PUPPETDB_CERT = '/var/lib/puppet/ssl/certs/test.networkninjas.net.pem'" } + end + end + + context 'AUTH ldap-dn' do + it 'works with no errors' do + pp = <<-EOS + # Configure Apache on this server + class { 'apache': } + class { 'apache::mod::authnz_ldap': } + -> class { 'puppetboard': + manage_virtualenv => true, + manage_git => true, + puppetdb_host => 'puppet.example.com', + puppetdb_port => 8081, + puppetdb_key => "/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem", + puppetdb_ssl_verify => true, + puppetdb_cert => "/var/lib/puppet/ssl/certs/test.networkninjas.net.pem", + require => Class['puppetdb'], + secret_key => 'this_should_be_a_long_secret_string', + } + class { 'puppetboard::apache::conf': + enable_ldap_auth => true, + ldap_bind_dn => 'cn=user,dc=puppet,dc=example,dc=com', + ldap_bind_password => 'password', + ldap_url => 'ldap://puppet.example.com', + ldap_require_dn => 'cn=admin,o=example', + } + # Configure PuppetDB + class { 'puppetdb': + disable_ssl => true, + manage_firewall => false, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_failures: true) + end + + describe file(apache_conf_file) do + it { is_expected.to contain 'AuthBasicProvider ldap' } + it { is_expected.to contain 'AuthLDAPBindDN "cn=user,dc=puppet,dc=example,dc=com"' } + it { is_expected.to contain 'AuthLDAPURL "ldap://puppet.example.com"' } + it { is_expected.to contain 'Require ldap-dn cn=admin,o=example' } + end + + describe file('/srv/puppetboard/puppetboard/settings.py') do + it { is_expected.to contain "PUPPETDB_KEY = '/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem'" } + it { is_expected.to contain "PUPPETDB_CERT = '/var/lib/puppet/ssl/certs/test.networkninjas.net.pem'" } + end + end + + context 'AUTH ldap-attribute' do + it 'works with no errors' do + pp = <<-EOS + # Configure Apache on this server + class { 'apache': } + class { 'apache::mod::authnz_ldap': } + -> class { 'puppetboard': + manage_virtualenv => true, + manage_git => true, + puppetdb_host => 'puppet.example.com', + puppetdb_port => 8081, + puppetdb_key => "/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem", + puppetdb_ssl_verify => true, + puppetdb_cert => "/var/lib/puppet/ssl/certs/test.networkninjas.net.pem", + require => Class['puppetdb'], + secret_key => 'this_should_be_a_long_secret_string', + } + class { 'puppetboard::apache::conf': + enable_ldap_auth => true, + ldap_bind_dn => 'cn=user,dc=puppet,dc=example,dc=com', + ldap_bind_password => 'password', + ldap_url => 'ldap://puppet.example.com', + ldap_require_attribute => 'role=admin status=active', + } + # Configure PuppetDB + class { 'puppetdb': + disable_ssl => true, + manage_firewall => false, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_failures: true) + end + + describe file(apache_conf_file) do + it { is_expected.to contain 'AuthBasicProvider ldap' } + it { is_expected.to contain 'AuthLDAPBindDN "cn=user,dc=puppet,dc=example,dc=com"' } + it { is_expected.to contain 'AuthLDAPURL "ldap://puppet.example.com"' } + it { is_expected.to contain 'Require ldap-attribute role=admin status=active' } + end + + describe file('/srv/puppetboard/puppetboard/settings.py') do + it { is_expected.to contain "PUPPETDB_KEY = '/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem'" } + it { is_expected.to contain "PUPPETDB_CERT = '/var/lib/puppet/ssl/certs/test.networkninjas.net.pem'" } + end + end + + context 'AUTH ldap-filter' do + it 'works with no errors' do + pp = <<-EOS + # Configure Apache on this server + class { 'apache': } + class { 'apache::mod::authnz_ldap': } + -> class { 'puppetboard': + manage_virtualenv => true, + manage_git => true, + puppetdb_host => 'puppet.example.com', + puppetdb_port => 8081, + puppetdb_key => "/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem", + puppetdb_ssl_verify => true, + puppetdb_cert => "/var/lib/puppet/ssl/certs/test.networkninjas.net.pem", + require => Class['puppetdb'], + secret_key => 'this_should_be_a_long_secret_string', + } + class { 'puppetboard::apache::conf': + enable_ldap_auth => true, + ldap_bind_dn => 'cn=user,dc=puppet,dc=example,dc=com', + ldap_bind_password => 'password', + ldap_url => 'ldap://puppet.example.com', + ldap_require_filter => '&(role=sysadmin)(memberOf=g:puppetboard::ag:*)', + } + # Configure PuppetDB + class { 'puppetdb': + disable_ssl => true, + manage_firewall => false, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_failures: true) + end + + describe file(apache_conf_file) do + it { is_expected.to contain 'AuthBasicProvider ldap' } + it { is_expected.to contain 'AuthLDAPBindDN "cn=user,dc=puppet,dc=example,dc=com"' } + it { is_expected.to contain 'AuthLDAPURL "ldap://puppet.example.com"' } + it { is_expected.to contain 'Require ldap-filter &(role=sysadmin)(memberOf=g:puppetboard::ag:*)' } + end + + describe file('/srv/puppetboard/puppetboard/settings.py') do + it { is_expected.to contain "PUPPETDB_KEY = '/var/lib/puppet/ssl/private_keys/test.networkninjas.net.pem'" } + it { is_expected.to contain "PUPPETDB_CERT = '/var/lib/puppet/ssl/certs/test.networkninjas.net.pem'" } + end + end end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index ef075c69..b41e55b9 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -4,7 +4,8 @@ configure_beaker do |host| # Install additional modules for soft deps - install_puppet_module_via_pmt_on(host, 'puppetlabs-puppetdb') + # Do not use puppetlabs-puppetdb 8.1.0, see its #412 + install_puppet_module_via_pmt_on(host, 'puppetlabs-puppetdb', '<= 8.0.1') install_puppet_module_via_pmt_on(host, 'puppetlabs-apache') install_puppet_module_via_pmt_on(host, 'puppet-epel') end diff --git a/templates/apache/conf.epp b/templates/apache/conf.epp index 9fcb8a7a..5178f637 100644 --- a/templates/apache/conf.epp +++ b/templates/apache/conf.epp @@ -32,9 +32,17 @@ WSGIScriptAlias <%= $wsgi_alias %> <%= $docroot %>/wsgi.py <%- if $ldap_bind_authoritative { %> AuthLDAPBindAuthoritative <%= $ldap_bind_authoritative %> <%- } %> - <%- if $ldap_require_group { %> + <%- if $ldap_require_user { %> + Require ldap-user <%= $ldap_require_user %> + <%- } elsif $ldap_require_group { %> Require ldap-group <%= $ldap_require_group_dn %> - <% } else { %> + <%- } elsif $ldap_require_dn { %> + Require ldap-dn <%= $ldap_require_dn %> + <%- } elsif $ldap_require_attribute { %> + Require ldap-attribute <%= $ldap_require_attribute %> + <%- } elsif $ldap_require_filter { %> + Require ldap-filter <%= $ldap_require_filter %> + <% } else { %> Require valid-user <% } %> diff --git a/templates/apache/ldap.epp b/templates/apache/ldap.epp index 31fad32a..0afb1997 100644 --- a/templates/apache/ldap.epp +++ b/templates/apache/ldap.epp @@ -17,9 +17,17 @@ <%- if $ldap_bind_authoritative { %> AuthLDAPBindAuthoritative <%= $ldap_bind_authoritative %> <%- } %> - <%- if $ldap_require_group { %> + <%- if $ldap_require_user { %> + Require ldap-user <%= $ldap_require_user %> + <%- } elsif $ldap_require_group { %> Require ldap-group <%= $ldap_require_group_dn %> - <% } else { %> + <%- } elsif $ldap_require_dn { %> + Require ldap-dn <%= $ldap_require_dn %> + <%- } elsif $ldap_require_attribute { %> + Require ldap-attribute <%= $ldap_require_attribute %> + <%- } elsif $ldap_require_filter { %> + Require ldap-filter <%= $ldap_require_filter %> + <% } else { %> Require valid-user <% } %>