Enable support for LDAP authentication
This patch allows to authenticate Grafana users against LDAP. It also supports a group-based authorization mapping to the admin and viewers roles. In this implementation we only support POSIX LDAP schemas. All options are disabled by default. DocImpact Add support for LDAP Implements: blueprint ldap-integration-in-stacklight Change-Id: I7e836d0cd8a5f7df3d934e29bfae337abd90da3c
This commit is contained in:
parent
d391f2b77b
commit
7bf3b41572
@ -22,6 +22,26 @@ $db_password = $influxdb_grafana['mysql_password']
|
||||
$admin_username = $influxdb_grafana['grafana_username']
|
||||
$admin_password = $influxdb_grafana['grafana_userpass']
|
||||
|
||||
$ldap_enabled = hiera('lma::grafana::ldap::enabled')
|
||||
if $ldap_enabled {
|
||||
$ldap_parameters = {
|
||||
servers => hiera('lma::grafana::ldap::servers'),
|
||||
protocol => hiera('lma::grafana::ldap::protocol'),
|
||||
port => hiera('lma::grafana::ldap::port'),
|
||||
bind_dn => hiera('lma::grafana::ldap::bind_dn'),
|
||||
bind_password => hiera('lma::grafana::ldap::bind_password'),
|
||||
user_search_base_dns => hiera('lma::grafana::ldap::user_search_base_dns'),
|
||||
user_search_filter => hiera('lma::grafana::ldap::user_search_filter'),
|
||||
authorization_enabled => hiera('lma::grafana::ldap::authorization_enabled'),
|
||||
group_search_base_dns => hiera('lma::grafana::ldap::group_search_base_dns'),
|
||||
group_search_filter => hiera('lma::grafana::ldap::group_search_filter'),
|
||||
admin_group_dn => hiera('lma::grafana::ldap::admin_group_dn', ''),
|
||||
viewer_group_dn => hiera('lma::grafana::ldap::viewer_group_dn', ''),
|
||||
}
|
||||
} else {
|
||||
$ldap_parameters = undef
|
||||
}
|
||||
|
||||
case $db_mode {
|
||||
|
||||
'local': {
|
||||
@ -38,13 +58,15 @@ case $db_mode {
|
||||
}
|
||||
|
||||
class {'lma_monitoring_analytics::grafana':
|
||||
db_host => $db_host,
|
||||
db_name => $db_name,
|
||||
db_username => $db_username,
|
||||
db_password => $db_password,
|
||||
admin_username => $admin_username,
|
||||
admin_password => $admin_password,
|
||||
domain => hiera('lma::influxdb::vip'),
|
||||
http_port => hiera('lma::influxdb::grafana_port'),
|
||||
version => '3.0.4-1464167696',
|
||||
db_host => $db_host,
|
||||
db_name => $db_name,
|
||||
db_username => $db_username,
|
||||
db_password => $db_password,
|
||||
admin_username => $admin_username,
|
||||
admin_password => $admin_password,
|
||||
domain => hiera('lma::influxdb::vip'),
|
||||
http_port => hiera('lma::influxdb::grafana_port'),
|
||||
version => '3.0.4-1464167696',
|
||||
ldap_enabled => $ldap_enabled,
|
||||
ldap_parameters => $ldap_parameters,
|
||||
}
|
||||
|
@ -61,6 +61,29 @@ if $tls_enabled {
|
||||
}
|
||||
}
|
||||
|
||||
$ldap_enabled = $influxdb_grafana['ldap_enabled']
|
||||
$ldap_protocol = $influxdb_grafana['ldap_protocol']
|
||||
$ldap_servers = $influxdb_grafana['ldap_servers']
|
||||
$ldap_bind_dn = $influxdb_grafana['ldap_bind_dn']
|
||||
$ldap_bind_password = $influxdb_grafana['ldap_bind_password']
|
||||
$ldap_user_search_base_dns = $influxdb_grafana['ldap_user_search_base_dns']
|
||||
$ldap_user_search_filter = $influxdb_grafana['ldap_user_search_filter']
|
||||
$ldap_authorization_enabled = $influxdb_grafana['ldap_authorization_enabled']
|
||||
$ldap_group_search_base_dns = $influxdb_grafana['ldap_group_search_base_dns']
|
||||
$ldap_group_search_filter = $influxdb_grafana['ldap_group_search_filter']
|
||||
$ldap_admin_group_dn = $influxdb_grafana['ldap_admin_group_dn']
|
||||
$ldap_viewer_group_dn = $influxdb_grafana['ldap_viewer_group_dn']
|
||||
|
||||
if empty($ldap_port) {
|
||||
if downcase($ldap_protocol) == 'ldap' {
|
||||
$ldap_port = 389
|
||||
} else {
|
||||
$ldap_port = 636
|
||||
}
|
||||
} else {
|
||||
$ldap_port = $influxdb_grafana['ldap_server_port']
|
||||
}
|
||||
|
||||
$calculated_content = inline_template('
|
||||
---
|
||||
lma::influxdb::data_dir: "/var/lib/influxdb"
|
||||
@ -83,6 +106,24 @@ lma::grafana::tls::enabled: <%= @tls_enabled %>
|
||||
lma::grafana::tls::hostname: "<%= @grafana_hostname %>"
|
||||
lma::grafana::tls::cert_file_path: "<%= @cert_file_path %>"
|
||||
<% end -%>
|
||||
|
||||
lma::grafana::ldap::enabled: <%= @ldap_enabled %>
|
||||
lma::grafana::ldap::authorization_enabled: <%= @ldap_authorization_enabled %>
|
||||
<% if @ldap_enabled -%>
|
||||
lma::grafana::ldap::servers: <%= @ldap_servers %>
|
||||
lma::grafana::ldap::protocol: <%= @ldap_protocol %>
|
||||
lma::grafana::ldap::port: <%= @ldap_port %>
|
||||
lma::grafana::ldap::bind_dn: <%= @ldap_bind_dn %>
|
||||
lma::grafana::ldap::bind_password: <%= @ldap_bind_password %>
|
||||
lma::grafana::ldap::user_search_base_dns: <%= @ldap_user_search_base_dns %>
|
||||
lma::grafana::ldap::user_search_filter: <%= @ldap_user_search_filter %>
|
||||
lma::grafana::ldap::group_search_base_dns: <%= @ldap_group_search_base_dns %>
|
||||
lma::grafana::ldap::group_search_filter: <%= @ldap_group_search_filter %>
|
||||
<% if @ldap_authorization_enabled -%>
|
||||
lma::grafana::ldap::admin_group_dn:<%= @ldap_admin_group_dn %>
|
||||
lma::grafana::ldap::viewer_group_dn: <%= @ldap_viewer_group_dn %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
')
|
||||
|
||||
file { $hiera_file:
|
||||
|
@ -24,6 +24,8 @@ class lma_monitoring_analytics::grafana (
|
||||
$domain = $lma_monitoring_analytics::params::grafana_domain,
|
||||
$http_address = $lma_monitoring_analytics::params::grafana_address,
|
||||
$http_port = $lma_monitoring_analytics::params::grafana_port,
|
||||
$ldap_enabled = false,
|
||||
$ldap_parameters = undef,
|
||||
$version = 'latest',
|
||||
) inherits lma_monitoring_analytics::params {
|
||||
|
||||
@ -32,6 +34,9 @@ class lma_monitoring_analytics::grafana (
|
||||
validate_string($db_username)
|
||||
validate_string($db_password)
|
||||
validate_string($http_address)
|
||||
if $ldap_enabled {
|
||||
validate_hash($ldap_parameters)
|
||||
}
|
||||
|
||||
# If no port is specified Grafana will not start. So we check if the
|
||||
# variable contains a port value and if not, we add ':3306'.
|
||||
@ -41,33 +46,64 @@ class lma_monitoring_analytics::grafana (
|
||||
$full_db_host = "${db_host}:3306"
|
||||
}
|
||||
|
||||
$ldap_configuration_file = '/etc/grafana/ldap.toml'
|
||||
|
||||
class { '::grafana':
|
||||
install_method => 'repo',
|
||||
version => $version,
|
||||
manage_package_repo => false,
|
||||
cfg => {
|
||||
server => {
|
||||
server => {
|
||||
http_address => $http_address,
|
||||
http_port => $http_port,
|
||||
domain => $domain,
|
||||
},
|
||||
database => {
|
||||
database => {
|
||||
type => 'mysql',
|
||||
host => $full_db_host,
|
||||
name => $db_name,
|
||||
user => $db_username,
|
||||
password => $db_password,
|
||||
},
|
||||
security => {
|
||||
'auth.ldap' => {
|
||||
enabled => $ldap_enabled,
|
||||
config_file => $ldap_configuration_file,
|
||||
},
|
||||
security => {
|
||||
admin_user => $admin_username,
|
||||
admin_password => $admin_password,
|
||||
},
|
||||
analytics => {
|
||||
analytics => {
|
||||
reporting_enabled => false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if $ldap_enabled {
|
||||
|
||||
# Following parameters are used in ldap.toml.erb
|
||||
$ldap_servers = $ldap_parameters['servers']
|
||||
$ldap_protocol = $ldap_parameters['protocol']
|
||||
$ldap_server_port = $ldap_parameters['port']
|
||||
$ldap_bind_dn = $ldap_parameters['bind_dn']
|
||||
$ldap_bind_password = $ldap_parameters['bind_password']
|
||||
$ldap_user_search_base_dns = $ldap_parameters['user_search_base_dns']
|
||||
$ldap_user_search_filter = $ldap_parameters['user_search_filter']
|
||||
$ldap_authorization_enabled = $ldap_parameters['authorization_enabled']
|
||||
$ldap_group_search_base_dns = $ldap_parameters['group_search_base_dns']
|
||||
$ldap_group_search_filter = $ldap_parameters['group_search_filter']
|
||||
$ldap_admin_group_dn = $ldap_parameters['admin_group_dn']
|
||||
$ldap_viewer_group_dn = $ldap_parameters['viewer_group_dn']
|
||||
|
||||
file { $ldap_configuration_file:
|
||||
owner => 'root',
|
||||
group => 'grafana',
|
||||
mode => '0640',
|
||||
content => template('lma_monitoring_analytics/ldap.toml.erb'),
|
||||
notify => Service['grafana-server'],
|
||||
}
|
||||
}
|
||||
|
||||
file { '/etc/logrotate.d/grafana.conf':
|
||||
ensure => present,
|
||||
content => template('lma_monitoring_analytics/logrotate.conf.erb'),
|
||||
|
@ -28,10 +28,96 @@ describe 'lma_monitoring_analytics::grafana', :type => :class do
|
||||
it { is_expected.to contain_package('grafana').with(
|
||||
:ensure => 'latest'
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_file('/etc/logrotate.d/grafana.conf') }
|
||||
end
|
||||
|
||||
describe 'with ldap' do
|
||||
let (:params) do
|
||||
{:db_host => 'localhost:3306',
|
||||
:db_name => 'grafana',
|
||||
:db_username => 'grafana',
|
||||
:db_password => 'grafana',
|
||||
:ldap_enabled => true,
|
||||
:ldap_parameters => {
|
||||
'servers' => 'localhost',
|
||||
'protocol' => 'ldap',
|
||||
'port' => 389,
|
||||
'bind_dn' => 'cn=admin,dc=example,dc=com',
|
||||
'bind_password' => 'pass',
|
||||
'user_search_base_dns' => 'dc=example,dc=com',
|
||||
'user_search_filter' => '(cn=%s)',
|
||||
'authorization_enabled' => false,
|
||||
'group_search_base_dns' => 'ou=groups,dc=example,dc=com',
|
||||
'group_search_filter' => '(&(objectClass=posixGroup)(memberUid=%s))',
|
||||
'admin_group_dn' => 'cn=admin_group,dc=example,dc=com',
|
||||
'viewer_group_dn' => 'cn=viewer_group,dc=example,dc=com',
|
||||
}
|
||||
}
|
||||
end
|
||||
it do
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/port\s*=\s*389/)
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/use_ssl\s*=\s*false/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with ldaps' do
|
||||
let (:params) do
|
||||
{:db_host => 'localhost:3306',
|
||||
:db_name => 'grafana',
|
||||
:db_username => 'grafana',
|
||||
:db_password => 'grafana',
|
||||
:ldap_enabled => true,
|
||||
:ldap_parameters => {
|
||||
'servers' => 'localhost',
|
||||
'protocol' => 'ldaps',
|
||||
'port' => '636',
|
||||
'bind_dn' => 'cn=admin,dc=example,dc=com',
|
||||
'bind_password' => 'pass',
|
||||
'user_search_base_dns' => 'dc=example,dc=com',
|
||||
'user_search_filter' => '(cn=%s)',
|
||||
'authorization_enabled' => false,
|
||||
'group_search_base_dns' => 'ou=groups,dc=example,dc=com',
|
||||
'group_search_filter' => '(&(objectClass=posixGroup)(memberUid=%s))',
|
||||
'admin_group_dn' => 'cn=admin_group,dc=example,dc=com',
|
||||
'viewer_group_dn' => 'cn=viewer_group,dc=example,dc=com',
|
||||
}
|
||||
}
|
||||
end
|
||||
it do
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/port\s*=\s*636/)
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/use_ssl\s*=\s*true/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with ldap and groups' do
|
||||
let (:params) do
|
||||
{:db_host => 'localhost:3306',
|
||||
:db_name => 'grafana',
|
||||
:db_username => 'grafana',
|
||||
:db_password => 'grafana',
|
||||
:ldap_enabled => true,
|
||||
:ldap_parameters => {
|
||||
'servers' => 'localhost',
|
||||
'protocol' => 'ldap',
|
||||
'port' => 389,
|
||||
'bind_dn' => 'cn=admin,dc=example,dc=com',
|
||||
'bind_password' => 'pass',
|
||||
'user_search_base_dns' => 'dc=example,dc=com',
|
||||
'user_search_filter' => '(cn=%s)',
|
||||
'authorization_enabled' => true,
|
||||
'group_search_base_dns' => 'ou=groups,dc=example,dc=com',
|
||||
'group_search_filter' => '(&(objectClass=posixGroup)(memberUid=%s))',
|
||||
'admin_group_dn' => 'cn=admin_group,dc=example,dc=com',
|
||||
'viewer_group_dn' => 'cn=viewer_group,dc=example,dc=com',
|
||||
}
|
||||
}
|
||||
end
|
||||
it do
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/group_dn = "cn=admin_group,dc=example,dc=com"/)
|
||||
should contain_file('/etc/grafana/ldap.toml').with_content(/group_dn = "cn=viewer_group,dc=example,dc=com"/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'db_host without port number' do
|
||||
let (:params) do
|
||||
{:db_host => 'www.example.com',
|
||||
|
@ -0,0 +1,42 @@
|
||||
[[servers]]
|
||||
host = "<%= @ldap_servers %>"
|
||||
port = <%= @ldap_server_port %>
|
||||
|
||||
<% if @ldap_protocol.downcase() == 'ldaps' -%>
|
||||
use_ssl = true
|
||||
<% else -%>
|
||||
use_ssl = false
|
||||
<% end -%>
|
||||
|
||||
ssl_skip_verify = true
|
||||
bind_dn = "<%= @ldap_bind_dn %>"
|
||||
bind_password = "<%= @ldap_bind_password %>"
|
||||
search_base_dns = [<%= @ldap_user_search_base_dns.split(' ').collect{|x| "\"#{x}\"" }.join(',') %>]
|
||||
search_filter = "<%= @ldap_user_search_filter %>"
|
||||
|
||||
# In POSIX LDAP schemas, without memberOf attribute a secondary query must be
|
||||
# made for groups. This is done by enabling group_search_filter below. We must
|
||||
# also set member_of="cn".
|
||||
group_search_base_dns = [<%= @ldap_group_search_base_dns.split(' ').collect{|x| "\"#{x}\"" }.join(',') %>]
|
||||
group_search_filter = "<%= @ldap_group_search_filter %>"
|
||||
|
||||
[servers.attributes]
|
||||
name = "givenName"
|
||||
surname = "sn"
|
||||
username = "cn"
|
||||
member_of = "cn"
|
||||
email = "email"
|
||||
|
||||
<% if @ldap_authorization_enabled -%>
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "<%= @ldap_admin_group_dn %>"
|
||||
org_role = "Admin"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "<%= @ldap_viewer_group_dn %>"
|
||||
org_role = "Viewer"
|
||||
<% else -%>
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "*"
|
||||
org_role = "Admin"
|
||||
<% end -%>
|
@ -164,3 +164,140 @@ attributes:
|
||||
- condition: "settings:influxdb_grafana.tls_enabled.value == false"
|
||||
action: "hide"
|
||||
# TLS Settings: END
|
||||
|
||||
# LDAP Settings: BEGIN
|
||||
ldap_enabled:
|
||||
value: false
|
||||
label: 'Use LDAP for Grafana authentication'
|
||||
description: ''
|
||||
weight: 170
|
||||
type: "checkbox"
|
||||
|
||||
ldap_protocol:
|
||||
type: "radio"
|
||||
value: 'ldap'
|
||||
weight: 180
|
||||
label: 'LDAP protocol'
|
||||
values:
|
||||
- data: "ldap"
|
||||
label: "LDAP"
|
||||
- data: "ldaps"
|
||||
label: "LDAPS"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_servers:
|
||||
value: ''
|
||||
label: 'LDAP servers'
|
||||
description: 'Specify one or several LDAP servers separated by space.'
|
||||
weight: 190
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_server_port:
|
||||
value: ''
|
||||
label: 'Port'
|
||||
description: 'If empty, the default value is 389 for LDAP and 636 for LDAPS.'
|
||||
weight: 200
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_bind_dn:
|
||||
value: ''
|
||||
label: 'Bind DN'
|
||||
description: 'DN used to bind to the server when searching for entries.'
|
||||
weight: 210
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_bind_password:
|
||||
value: ''
|
||||
label: 'Bind password'
|
||||
description: 'Password to use in conjunction with the bind DN.'
|
||||
weight: 220
|
||||
type: "password"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_user_search_base_dns:
|
||||
value: ''
|
||||
label: 'User search base DN'
|
||||
description: 'The base DN to search for users.'
|
||||
weight: 230
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_user_search_filter:
|
||||
value: '(uid=%s)'
|
||||
label: 'User search filter'
|
||||
description: 'A valid LDAP search filter.'
|
||||
weight: 240
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_group_search_base_dns:
|
||||
value: ''
|
||||
label: 'Group search base DN'
|
||||
description: 'The base DN to search for groups.'
|
||||
weight: 250
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_group_search_filter:
|
||||
value: '(&(objectClass=posixGroup)(memberUid=%s)'
|
||||
label: 'Group search filter'
|
||||
description: 'A valid LDAP search filter.'
|
||||
weight: 260
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_authorization_enabled:
|
||||
value: false
|
||||
label: 'Enable group-based authorization'
|
||||
description: 'It allows to associate the users with the admin or read-only role. Otherwise all users are assigned to admin role.'
|
||||
weight: 270
|
||||
type: "checkbox"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
|
||||
ldap_admin_group_dn:
|
||||
value: ''
|
||||
label: 'Group DN mapping to the Admins role'
|
||||
description: ''
|
||||
weight: 280
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
- condition: "settings:influxdb_grafana.ldap_authorization_enabled.value == false"
|
||||
action: disable
|
||||
|
||||
ldap_viewer_group_dn:
|
||||
value: ''
|
||||
label: 'Group DN mapping to the Viewers role'
|
||||
description: ''
|
||||
weight: 290
|
||||
type: "text"
|
||||
restrictions:
|
||||
- condition: "settings:influxdb_grafana.ldap_enabled.value == false"
|
||||
action: hide
|
||||
- condition: "settings:influxdb_grafana.ldap_authorization_enabled.value == false"
|
||||
action: disable
|
||||
# LDAP Settings: END
|
||||
|
Loading…
Reference in New Issue
Block a user