Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend connection functionn to use ssl_mode #753

Merged
merged 1 commit into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading