Skip to content

Commit

Permalink
Merge pull request #753 from SimonHoenscheid/extend_connection_function
Browse files Browse the repository at this point in the history
Extend connection functionn to use ssl_mode
  • Loading branch information
lbetz authored Feb 5, 2024
2 parents f38a485 + 8b905aa commit 223be26
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 33 deletions.
19 changes: 10 additions & 9 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1695,12 +1695,7 @@ Default value: `'icinga'`

##### <a name="-icinga2--feature--idopgsql--ssl_mode"></a>`ssl_mode`

Data type:

```puppet
Optional[Enum['disable', 'allow', 'prefer',
'verify-full', 'verify-ca', 'require']]
```
Data type: `Optional[Enum['verify-full', 'verify-ca']]`

Enable SSL connection mode.

Expand Down Expand Up @@ -5603,7 +5598,7 @@ with or without TLS information.
database => String,
username => String,
password => Optional[Variant[String, Sensitive[String]]],
}] $db, Hash[String, Any] $tls, Optional[Boolean] $use_tls = undef)`
}] $db, Hash[String, Any] $tls, Optional[Boolean] $use_tls = undef, Optional[Enum['verify-full', 'verify-ca']] $ssl_mode = undef)`

The icinga2::db::connect function.

Expand All @@ -5624,19 +5619,25 @@ Struct[{
}]
```


Data hash with database information.

##### `tls`

Data type: `Hash[String, Any]`


Data hash with TLS connection information.

##### `use_tls`

Data type: `Optional[Boolean]`

Wether or not to use TLS encryption.

##### `ssl_mode`

Data type: `Optional[Enum['verify-full', 'verify-ca']]`

Enable SSL connection mode.

### <a name="icinga2--icinga2_attributes"></a>`icinga2::icinga2_attributes`

Expand Down
39 changes: 22 additions & 17 deletions functions/db/connect.pp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
# @return
# Connection string to connect database.
#
# @param db
# Data hash with database information.
#
# @param tls
# Data hash with TLS connection information.
#
# @param use_tls
# Wether or not to use TLS encryption.
#
# @param ssl_mode
# Enable SSL connection mode.
#
function icinga2::db::connect(
Struct[{
type => Enum['pgsql','mysql','mariadb'],
Expand All @@ -16,21 +28,14 @@ function icinga2::db::connect(
}] $db,
Hash[String, Any] $tls,
Optional[Boolean] $use_tls = undef,
Optional[Enum['verify-full', 'verify-ca']] $ssl_mode = undef,
) >> String {
# @param db
# Data hash with database information.
#
# @param tls
# Data hash with TLS connection information.
#
# @param use_tls
# Wether or not to use TLS encryption.
#
if $use_tls {
case $db['type'] {
'pgsql': {
$real_ssl_mode = if $ssl_mode { $ssl_mode } else { 'verify-full' }
$tls_options = regsubst(join(any2array(delete_undef_values({
'sslmode=' => if $tls['noverify'] { 'require' } else { 'verify-full' },
'sslmode=' => if $tls['noverify'] { 'require' } else { $real_ssl_mode },
'sslcert=' => $tls['cert_file'],
'sslkey=' => $tls['key_file'],
'sslrootcert=' => $tls['cacert_file'],
Expand All @@ -39,20 +44,20 @@ function icinga2::db::connect(
'mariadb': {
$tls_options = join(any2array(delete_undef_values({
'--ssl' => '',
'--ssl-ca' => $tls['cacert_file'],
'--ssl-ca' => if $tls['noverify'] { undef } else { $tls['cacert_file'] },
'--ssl-cert' => $tls['cert_file'],
'--ssl-key' => $tls['key_file'],
'--ssl-capath' => $tls['capath'],
'--ssl-capath' => if $tls['noverify'] { undef } else { $tls['capath'] },
'--ssl-cipher' => $tls['cipher'],
})), ' ')
}
'mysql': {
$tls_options = join(any2array(delete_undef_values({
'--ssl-mode' => 'required',
'--ssl-ca' => $tls['cacert_file'],
'--ssl-mode' => if $tls['noverify'] { 'REQUIRED' } else { 'VERIFY_CA' },
'--ssl-ca' => if $tls['noverify'] { undef } else { $tls['cacert_file'] },
'--ssl-cert' => $tls['cert_file'],
'--ssl-key' => $tls['key_file'],
'--ssl-capath' => $tls['capath'],
'--ssl-capath' => if $tls['noverify'] { undef } else { $tls['capath'] },
'--ssl-cipher' => $tls['cipher'],
})), ' ')
}
Expand Down Expand Up @@ -80,10 +85,10 @@ function icinga2::db::connect(
},
'-P' => $db['port'],
'-u' => $db['username'],
"-p'${_password}'" => '',
"-p'${_password}'" => if $db['password'] { '' } else { undef },
'-D' => $db['database'],
})), ' ')
}

"${options} ${tls_options}"
strip(regsubst("${options} ${tls_options}", '\s{2,}', ' '))
}
5 changes: 2 additions & 3 deletions manifests/feature/idopgsql.pp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@
Optional[Stdlib::Port::Unprivileged] $port = undef,
String $user = 'icinga',
String $database = 'icinga',
Optional[Enum['disable', 'allow', 'prefer',
'verify-full', 'verify-ca', 'require']] $ssl_mode = undef,
Optional[Enum['verify-full', 'verify-ca']] $ssl_mode = undef,
Optional[Stdlib::Absolutepath] $ssl_key_path = undef,
Optional[Stdlib::Absolutepath] $ssl_cert_path = undef,
Optional[Stdlib::Absolutepath] $ssl_cacert_path = undef,
Expand Down Expand Up @@ -212,7 +211,7 @@
'port' => $port,
'database' => $database,
'username' => $user,
}, $cert, $enable_ssl)
}, $cert, $enable_ssl, $ssl_mode)

exec { 'idopgsql-import-schema':
user => 'root',
Expand Down
6 changes: 3 additions & 3 deletions spec/classes/idomysql_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
is_expected.to contain_exec('idomysql-import-schema').with(
{
user: 'root',
command: "mysql -u icinga -p'foo' -D icinga < \"#{ido_mysql_schema_dir}/mysql.sql\"",
command: "mysql -u icinga -p'foo' -D icinga < \"#{ido_mysql_schema_dir}/mysql.sql\"",
},
)
}
Expand Down Expand Up @@ -186,7 +186,7 @@
is_expected.to contain_exec('idomysql-import-schema').with(
{
'user' => 'root',
'command' => "mysql -h 127.0.0.1 -P 3306 -u icinga -p'foo' -D icinga --ssl --ssl-ca #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql_ca.crt" \
'command' => "mysql -h 127.0.0.1 -P 3306 -u icinga -p'foo' -D icinga --ssl --ssl-ca #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql_ca.crt" \
" --ssl-cert #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql.crt --ssl-key #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql.key < \"#{ido_mysql_schema_dir}/mysql.sql\"",
},
)
Expand Down Expand Up @@ -227,7 +227,7 @@
is_expected.to contain_exec('idomysql-import-schema').with(
{
'user' => 'root',
'command' => "mysql -u icinga -p'foo' -D icinga --ssl --ssl-ca #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql_ca.crt" \
'command' => "mysql -u icinga -p'foo' -D icinga --ssl --ssl-ca #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql_ca.crt" \
" --ssl-cert #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql.crt --ssl-key #{icinga2_pki_dir}/IdoMysqlConnection_ido-mysql.key < \"#{ido_mysql_schema_dir}/mysql.sql\"",
},
)
Expand Down
56 changes: 55 additions & 1 deletion spec/classes/idopgsql_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
{
'user' => 'root',
'environment' => ['PGPASSWORD=foo'],
'command' => "psql 'host=localhost user=icinga dbname=icinga ' -w -f '#{ido_pgsql_schema_dir}/pgsql.sql'",
'command' => "psql 'host=localhost user=icinga dbname=icinga' -w -f '#{ido_pgsql_schema_dir}/pgsql.sql'",
},
)
}
Expand Down Expand Up @@ -177,6 +177,60 @@
)
}
end

context "with ssl_mode => verify-ca, host => '192.168.0.1', port => 5432, import_schema => true, ssl_key => 'foo', ssl_cert => 'bar', ssl_cacert => 'baz'" do
let(:params) do
{
ssl_mode: 'verify-ca',
ssl_key: 'foo',
ssl_cert: 'bar',
ssl_cacert: 'baz',
host: '192.168.0.1',
port: 5432,
import_schema: true,
password: 'foo',
}
end

it {
is_expected.to contain_file("#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql.key").with(
{
'mode' => icinga2_sslkey_mode,
'owner' => icinga2_user,
'group' => icinga2_group,
},
).with_content(%r{^foo})
}

it {
is_expected.to contain_file("#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql.crt").with(
{
'owner' => icinga2_user,
'group' => icinga2_group,
},
).with_content(%r{^bar$})
}

it {
is_expected.to contain_file("#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql_ca.crt").with(
{
'owner' => icinga2_user,
'group' => icinga2_group,
},
).with_content(%r{^baz$})
}

it {
is_expected.to contain_exec('idopgsql-import-schema').with(
{
'user' => 'root',
'command' => "psql 'host=192.168.0.1 user=icinga port=5432 dbname=icinga sslmode=verify-ca sslcert=#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql.crt " \
"sslkey=#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql.key sslrootcert=#{icinga2_pki_dir}/IdoPgsqlConnection_ido-pgsql_ca.crt' " \
"-w -f '#{ido_pgsql_schema_dir}/pgsql.sql'",
},
)
}
end
end
end
end
102 changes: 102 additions & 0 deletions spec/functions/db_connect_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
require 'spec_helper'

describe 'icinga2::db::connect' do
it { is_expected.not_to eq(nil) }

it 'with MySQL/MariaDB' do
is_expected.to run.with_params(
{ 'type' => 'mysql', 'host' => 'localhost', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' }, {}
).and_return("-u bar -p'supersecret' -D foo")
end

it 'with MySQL/MariaDB on db.example.org and port 4711' do
is_expected.to run.with_params(
{ 'type' => 'mysql', 'host' => 'db.example.org', 'port' => 4711, 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' }, {}
).and_return("-h db.example.org -P 4711 -u bar -p'supersecret' -D foo")
end

it 'with MariaDB TLS on db.example.org and password' do
is_expected.to run.with_params(
{ 'type' => 'mariadb', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'cacert_file' => '/cacert.file' },
true,
).and_return("-h db.example.org -u bar -p'supersecret' -D foo --ssl --ssl-ca /cacert.file")
end

it "with MariaDB TLS and noverify 'true' on db.example.org and password" do
is_expected.to run.with_params(
{ 'type' => 'mariadb', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'noverify' => true, 'cacert_file' => '/cacert.file' },
true,
).and_return("-h db.example.org -u bar -p'supersecret' -D foo --ssl")
end

it 'with MariaDB client TLS cert on db.example.org' do
is_expected.to run.with_params(
{ 'type' => 'mariadb', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar' },
{ 'key_file' => '/key.file', 'cert_file' => '/cert.file', 'cacert_file' => '/cacert.file' },
true,
).and_return('-h db.example.org -u bar -D foo --ssl --ssl-ca /cacert.file --ssl-cert /cert.file --ssl-key /key.file')
end

it 'with MySQL client TLS cert on db.example.org' do
is_expected.to run.with_params(
{ 'type' => 'mysql', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar' },
{ 'key_file' => '/key.file', 'cert_file' => '/cert.file', 'cacert_file' => '/cacert.file' },
true,
).and_return('-h db.example.org -u bar -D foo --ssl-mode VERIFY_CA --ssl-ca /cacert.file --ssl-cert /cert.file --ssl-key /key.file')
end

it "with MySQL TLS and noverify 'true' on db.example.org and password" do
is_expected.to run.with_params(
{ 'type' => 'mysql', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'noverify' => true, 'cacert_file' => '/cacert.file' },
true,
).and_return("-h db.example.org -u bar -p'supersecret' -D foo --ssl-mode REQUIRED")
end

it 'with PostgreSQL' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => 'localhost', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' }, {}
).and_return('host=localhost user=bar dbname=foo')
end

it 'with PostgreSQL on db.example.org and port 4711' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => 'db.example.org', 'port' => 4711, 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' }, {}
).and_return('host=db.example.org user=bar port=4711 dbname=foo')
end

it 'with PostgreSQL TLS on db.example.org and password' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'cacert_file' => '/cacert.file' },
true,
).and_return('host=db.example.org user=bar dbname=foo sslmode=verify-full sslrootcert=/cacert.file')
end

it 'with PostgreSQL TLS on 192.168.0.1 and password' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => '192.168.0.1', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'cacert_file' => '/etc/pki/ca-trust/source/anchors/mycacert.crt' },
true,
'verify-ca',
).and_return('host=192.168.0.1 user=bar dbname=foo sslmode=verify-ca sslrootcert=/etc/pki/ca-trust/source/anchors/mycacert.crt')
end

it 'with PostgreSQL TLS (insecure) on db.example.org and password' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar', 'password' => 'supersecret' },
{ 'noverify' => true },
true,
).and_return('host=db.example.org user=bar dbname=foo sslmode=require')
end

it 'with PostgreSQL client TLS cert on db.example.org' do
is_expected.to run.with_params(
{ 'type' => 'pgsql', 'host' => 'db.example.org', 'database' => 'foo', 'username' => 'bar' },
{ 'key_file' => '/key.file', 'cert_file' => '/cert.file', 'cacert_file' => '/cacert.file' },
true,
).and_return('host=db.example.org user=bar dbname=foo sslmode=verify-full sslcert=/cert.file sslkey=/key.file sslrootcert=/cacert.file')
end
end

0 comments on commit 223be26

Please sign in to comment.