diff --git a/hieradata/roles/infra/metrics/grafana.eyaml b/hieradata/roles/infra/metrics/grafana.eyaml new file mode 100644 index 0000000..575f547 --- /dev/null +++ b/hieradata/roles/infra/metrics/grafana.eyaml @@ -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=] diff --git a/hieradata/roles/infra/metrics/grafana.yaml b/hieradata/roles/infra/metrics/grafana.yaml index 826065d..6f81f06 100644 --- a/hieradata/roles/infra/metrics/grafana.yaml +++ b/hieradata/roles/infra/metrics/grafana.yaml @@ -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: diff --git a/modules/libs/lib/facter/psql_is_slave.rb b/modules/libs/lib/facter/psql_is_slave.rb index 5478e5e..f181f21 100644 --- a/modules/libs/lib/facter/psql_is_slave.rb +++ b/modules/libs/lib/facter/psql_is_slave.rb @@ -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()"' diff --git a/site/profiles/manifests/metrics/grafana.pp b/site/profiles/manifests/metrics/grafana.pp index c7cd7ab..c792c4c 100644 --- a/site/profiles/manifests/metrics/grafana.pp +++ b/site/profiles/manifests/metrics/grafana.pp @@ -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 diff --git a/site/profiles/manifests/sql/patroni.pp b/site/profiles/manifests/sql/patroni.pp index ea29403..07bcfa7 100644 --- a/site/profiles/manifests/sql/patroni.pp +++ b/site/profiles/manifests/sql/patroni.pp @@ -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 |>> {} } diff --git a/site/profiles/manifests/sql/postgres/db.pp b/site/profiles/manifests/sql/postgres/db.pp index 586820e..9342ed9 100644 --- a/site/profiles/manifests/sql/postgres/db.pp +++ b/site/profiles/manifests/sql/postgres/db.pp @@ -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}'", } } - diff --git a/site/profiles/manifests/sql/postgres/grant.pp b/site/profiles/manifests/sql/postgres/grant.pp index 2f8476e..92daf9d 100644 --- a/site/profiles/manifests/sql/postgres/grant.pp +++ b/site/profiles/manifests/sql/postgres/grant.pp @@ -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, } } diff --git a/site/profiles/manifests/sql/postgresdb.pp b/site/profiles/manifests/sql/postgresdb.pp index 2497e8c..f06b2ed 100644 --- a/site/profiles/manifests/sql/postgresdb.pp +++ b/site/profiles/manifests/sql/postgresdb.pp @@ -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, + # } + #} } }