benvin/grafana_postgres (#334)

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/334
This commit is contained in:
Ben Vincent 2025-07-01 19:07:24 +10:00
parent 61d912de30
commit a9faa098ee
8 changed files with 115 additions and 51 deletions

View File

@ -0,0 +1,3 @@
---
profiles::sql::postgresdb::dbpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAnG+tRQ71dgDjsILb0Ay81eIassCOdBSS3d9g+nAXzHfdW+WGA5MbqEJ9ooQrrwsjf2rz4fK54X5WPw+vt45e5o6STjdY8TOk7dc881+ABbAyMi4eEVhIJ39saZuIPueEu+HmqySjUl3Qwz/8y4sCav0T5LLusIz1koW9vAxX11tBp/kKwwZZH/PaIj7le3hZm3+BlAPntjrErGL8u5h8tL+bRA/I1NmPZFXZ7Nj0nfLK6hWnCJfQn28Q3MuIa9Fb65+eOQeoBzn2q6qOz1kYvopoj0XQ/Vwn/EPOAppdROBa3ryMGsEWe9tLD/RQdAejAxOepg8wnO/6YzJoFniTNzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDgkT0peDegh86u5IkQwDnNgDCHSJ+zs6lkpagS4ZOEGBxm6hPbIj0pbY20P4Dt+WeuYPqjiL7iVGQp810tVptjIbY=]
profiles::metrics::grafana::ldap_bind_pass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAO4xWWXGFjryWBT8o5OdB9DEWneSMgy1u2x6eYe0wiNdPmbSO/jVVZPDkXwPn2C5fPJ4YoHNoUMjNX+ykbVyWKINr+OmlaI7etOtaQzoinBoATXIyz8GoDjQDSmTFWjcfDaB0yHnhQw1ThDycO5v5tT3/IAETPO7EC/HsRriiMsSx64eu7a0aN1wtd1ztwHANv+RIozFwuWNV41JpmIRpWox/wLWVra59Merju+7F/kH95M1WIZ04ZutJw3pTvOXdzKb1LkDPzgqga7PNgSWAjMcfxoz1zifWOV3jNTS2j01PLDHO64eAFFK4LaYg2ZL+5oc8ZvoF9Bsf82P7xR6S/zBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBDgsLSjEI2ZV3+GQQRDpSwgDB1kt23gUX8+tpCXg2E3GdAW05gztE0U5rVBlRHpeOU/2Ddiyuqdg2rOFFxXqd4av4=]

View File

@ -2,8 +2,15 @@
hiera_include:
- profiles::nginx::simpleproxy
profiles::metrics::grafana::mysql_host: "mariadb-%{facts.environment}.service.%{facts.country}-%{facts.region}.consul"
profiles::metrics::grafana::mysql_port: 3306
profiles::sql::postgresdb::cluster_name: "patroni-shared-%{facts.environment}"
profiles::sql::postgresdb::dbname: grafana
profiles::sql::postgresdb::dbuser: grafana
profiles::metrics::grafana::db_host: "master.%{hiera('profiles::sql::postgresdb::cluster_name')}.service.%{facts.country}-%{facts.region}.consul"
profiles::metrics::grafana::db_port: 5432
profiles::metrics::grafana::db_name: "%{hiera('profiles::sql::postgresdb::dbname')}"
profiles::metrics::grafana::db_user: "%{hiera('profiles::sql::postgresdb::dbuser')}"
profiles::metrics::grafana::db_pass: "%{hiera('profiles::sql::postgresdb::dbpass')}"
profiles::metrics::grafana::pgsql_backend: true
# additional altnames
profiles::pki::vault::alt_names:

View File

@ -1,7 +1,11 @@
# frozen_string_literal: true
Facter.add(:psql_is_slave) do
confine enc_role: 'roles::infra::sql::patroni'
confine enc_role: [
'roles::infra::sql::patroni',
'roles::infra::sql::shared',
'roles::infra::puppetdb::sql'
]
setcode do
# Command to check if PostgreSQL is in recovery mode
command = 'sudo -iu postgres psql -tAc "select pg_is_in_recovery()"'

View File

@ -1,15 +1,16 @@
# profiles::metrics::grafana
class profiles::metrics::grafana (
String $ldap_bind_pass,
Stdlib::Port $http_port = 8080,
String $app_mode = 'production',
Boolean $allow_sign_up = false,
Boolean $mysql_backend = true,
String $mysql_user = 'grafana',
String $mysql_name = 'grafana',
String $mysql_pass = fqdn_rand_string(16),
Stdlib::Host $mysql_host = '127.0.0.1',
Stdlib::Port $mysql_port = 3306,
Boolean $mysql_backend = false,
Boolean $pgsql_backend = false,
String $db_user = 'grafana',
String $db_name = 'grafana',
String $db_pass = fqdn_rand_string(16),
Stdlib::Host $db_host = '127.0.0.1',
Stdlib::Port $db_port = 5432,
) {
# set the fqdn
@ -18,26 +19,40 @@ class profiles::metrics::grafana (
# when using mysql backend
if $mysql_backend {
@@mysql_user { "${mysql_user}@${facts['networking']['fqdn']}":
@@mysql_user { "${db_user}@${facts['networking']['fqdn']}":
ensure => present,
password_hash => mysql::password(fqdn_rand_string(16)),
password_hash => mysql::password($db_pass),
tag => $facts['region'],
}
@@mysql_grant { "${mysql_user}@${facts['networking']['fqdn']}/${mysql_name}.*":
@@mysql_grant { "${db_user}@${facts['networking']['fqdn']}/${db_name}.*":
ensure => present,
table => "${mysql_name}.*",
user => "${mysql_user}@${facts['networking']['fqdn']}",
table => "${db_name}.*",
user => "${db_user}@${facts['networking']['fqdn']}",
privileges => ['ALL'],
tag => $facts['region'],
}
$database_config = {
type => 'mysql',
host => "${mysql_host}:${mysql_port}",
name => $mysql_name,
user => $mysql_user,
password => $mysql_pass.unwrap,
host => "${db_host}:${db_port}",
name => $db_name,
user => $db_user,
password => $db_pass.unwrap,
}
}
# when using mysql backend
if $pgsql_backend {
include profiles::sql::postgresdb
$database_config = {
type => 'postgres',
host => "${db_host}:${db_port}",
name => $db_name,
user => $db_user,
password => $db_pass.unwrap,
}
}
@ -51,11 +66,48 @@ class profiles::metrics::grafana (
users => {
allow_sign_up => $allow_sign_up,
},
'auth.ldap' => {
enabled => 'true',
config_file => '/etc/grafana/ldap.toml',
},
}
# build the ldap config hash
$ldap_cfg = Sensitive({
servers => [
{ host => 'ldap.service.consul',
port => 389,
use_ssl => false,
search_filter => '(uid=%s)',
search_base_dns => [ 'dc=main,dc=unkin,dc=net' ],
bind_dn => 'cn=svc_grafana,ou=services,ou=users,dc=main,dc=unkin,dc=net',
bind_password => $ldap_bind_pass,
},
],
'servers.attributes' => {
name => 'givenName',
surname => 'sn',
username => 'uid',
member_of => 'memberOf',
email => 'mail',
},
'servers.group_mappings' => [
{
group_dn => 'ou=grafana_admin,ou=groups,dc=main,dc=unkin,dc=net',
org_role => 'Admin',
grafana_admin => true,
},
{
group_dn => 'ou=grafana_user,ou=groups,dc=main,dc=unkin,dc=net',
org_role => 'Viewer',
}
],
})
# deploy grafana
class { 'grafana':
cfg => $cfg,
cfg => $cfg,
ldap_cfg => $ldap_cfg,
}
# fix the package provided systemd service

View File

@ -88,8 +88,8 @@ class profiles::sql::patroni (
if ! $facts['psql_is_slave'] {
# collect exported resources
$tag = "${cluster_name}-${facts['country']}-${facts['region']}-${facts['environment']}"
Profiles::Sql::Postgres::Db <<| tag == $tag |>> {}
Profiles::Sql::Postgres::User <<| tag == $tag |>> {}
Profiles::Sql::Postgres::Db <<| tag == $tag |>> {}
Profiles::Sql::Postgres::Grant <<| tag == $tag |>> {}
}

View File

@ -1,9 +1,9 @@
define profiles::sql::postgres::db (
String $dbname,
String $owner,
) {
postgresql_psql { "create_database_${dbname}":
command => "CREATE DATABASE \"${dbname}\"",
command => "CREATE DATABASE \"${dbname}\" OWNER \"${owner}\"",
unless => "SELECT 1 FROM pg_database WHERE datname = '${dbname}'",
}
}

View File

@ -1,11 +1,10 @@
define profiles::sql::postgres::grant (
String $username,
String $privilege,
Enum['SCHEMA', 'DATABASE'] $type = 'DATABASE',
Optional[String] $dbname = undef,
Optional[String] $schema = undef,
String $privilege = 'ALL PRIVILEGES',
) {
# Validate parameters based on type
if $type == 'DATABASE' and $dbname == undef {
fail('The dbname parameter must be provided when type is DATABASE')
}
@ -14,25 +13,19 @@ define profiles::sql::postgres::grant (
fail('Both dbname and schema parameters must be provided when type is SCHEMA')
}
# Determine the appropriate SQL command and unless condition
$command = $type ? {
'DATABASE' => "GRANT ${privilege} ON DATABASE ${dbname} TO ${username}",
'SCHEMA' => "GRANT ${privilege} ON SCHEMA ${schema} TO ${username}",
}
$unless = $type ? {
'DATABASE' => "SELECT 1 FROM pg_roles r WHERE r.rolname='${username}' AND has_database_privilege('${username}', '${dbname}', 'CONNECT')", # lint:ignore:140chars
'SCHEMA' => "SELECT 1 FROM pg_namespace n JOIN pg_roles r ON r.oid = n.nspowner WHERE nspname = '${schema}' AND r.rolname = '${username}'", # lint:ignore:140chars
}
# Ensure the db parameter is set correctly when type is SCHEMA
$effective_dbname = $type ? {
'SCHEMA' => $dbname,
'DATABASE' => $dbname,
'DATABASE' => "SELECT 1 FROM pg_roles r WHERE r.rolname='${username}' AND has_database_privilege('${username}', '${dbname}', '${privilege}')", # lint:ignore:140chars
'SCHEMA' => undef,
}
postgresql_psql { "grant_${privilege}_on_${type}_${effective_dbname}_${schema}_to_${username}":
postgresql_psql { "grant_${privilege}_on_${type}_${dbname}_${schema}_to_${username}":
command => $command,
unless => $unless,
db => $effective_dbname,
db => $dbname,
}
}

View File

@ -4,8 +4,8 @@ class profiles::sql::postgresdb (
String $dbpass,
String $cluster_name,
Boolean $create_host_users = false,
Boolean $members_lookup = false,
String $members_role = undef,
Boolean $members_lookup = true,
String $members_role = $facts['enc_role'],
Array $servers = [],
){
@ -33,6 +33,7 @@ class profiles::sql::postgresdb (
# manage the postgres db
@@profiles::sql::postgres::db { "${facts['networking']['fqdn']}_db_${dbname}":
dbname => $dbname,
owner => $dbuser,
tag => $tag,
}
@ -42,21 +43,25 @@ class profiles::sql::postgresdb (
tag => $tag,
}
@@profiles::sql::postgres::grant { "${facts['networking']['fqdn']}_grant_db_${dbuser}_${dbuser}}":
dbname => $dbname,
username => $dbuser,
type => 'DATABASE',
privilege => 'ALL PRIVILEGES',
tag => $tag,
['CONNECT', 'CREATE', 'TEMPORARY'].each |$priv| {
@@profiles::sql::postgres::grant { "${facts['networking']['fqdn']}_grant_db_${dbname}_${dbuser}_${priv}":
dbname => $dbname,
username => $dbuser,
type => 'DATABASE',
privilege => $priv,
tag => $tag,
}
}
@@profiles::sql::postgres::grant { "${facts['networking']['fqdn']}_grant_schema_${dbuser}_${dbuser}}":
dbname => $dbname,
username => $dbuser,
type => 'SCHEMA',
schema => 'public',
privilege => 'ALL PRIVILEGES',
tag => $tag,
}
#['USAGE', 'CREATE'].each |$priv| {
# @@profiles::sql::postgres::grant { "${facts['networking']['fqdn']}_grant_schema_${dbname}_${dbuser}_${priv}":
# dbname => $dbname,
# username => $dbuser,
# type => 'SCHEMA',
# schema => 'public',
# privilege => $priv,
# tag => $tag,
# }
#}
}
}