diff --git a/manifests/backup/mysqldump.pp b/manifests/backup/mysqldump.pp index 2fba423c5..a7bfcb538 100644 --- a/manifests/backup/mysqldump.pp +++ b/manifests/backup/mysqldump.pp @@ -112,7 +112,6 @@ 'include_routines' => $include_routines, } - # TODO: use EPP instead of ERB, as EPP can handle Data of Type Sensitive without further ado file { 'mysqlbackup.sh': ensure => $ensure, path => '/usr/local/sbin/mysqlbackup.sh', diff --git a/manifests/backup/xtrabackup.pp b/manifests/backup/xtrabackup.pp index 1cf6910bb..efe465bbf 100644 --- a/manifests/backup/xtrabackup.pp +++ b/manifests/backup/xtrabackup.pp @@ -175,7 +175,6 @@ group => $backupdirgroup, } - # TODO: use EPP instead of ERB, as EPP can handle Data of Type Sensitive without further ado $parameters = { 'innobackupex_args' => mysql::innobackupex_args($backupuser, $backupcompress, $backuppassword_unsensitive, $backupdatabases, $optional_args), 'backuprotate' => $backuprotate, diff --git a/manifests/server.pp b/manifests/server.pp index 8748e33bc..153a4f2b7 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -99,7 +99,7 @@ Optional[Array[String[1]]] $install_options = undef, Variant[Boolean, String[1]] $manage_config_file = true, Mysql::Options $options = {}, - Hash $override_options = {}, + Mysql::OverrideOptions $override_options = {}, Variant[Enum['present','absent'], Pattern[/(\d+)[\.](\d+)[\.](\d+)/]] $package_ensure = 'present', Boolean $package_manage = true, String[1] $package_name = $mysql::params::server_package_name, diff --git a/manifests/server/root_password.pp b/manifests/server/root_password.pp index 91b047626..c17510b97 100644 --- a/manifests/server/root_password.pp +++ b/manifests/server/root_password.pp @@ -44,7 +44,6 @@ } if $mysql::server::create_root_my_cnf and $root_password_set { - # TODO: use EPP instead of ERB, as EPP can handle Data of Type Sensitive without further ado file { "${facts['root_home']}/.my.cnf": content => epp('mysql/my.cnf.pass.epp',$parameters), owner => 'root', diff --git a/spec/classes/mycnf_template_spec.rb b/spec/classes/mycnf_template_spec.rb index 8be85579f..35ecfd007 100644 --- a/spec/classes/mycnf_template_spec.rb +++ b/spec/classes/mycnf_template_spec.rb @@ -10,11 +10,44 @@ end context 'normal entry' do - let(:params) { { override_options: { 'mysqld' => { 'socket' => '/var/lib/mysql/mysql.sock' } } } } + let(:params) do + { + 'override_options' => { + 'mysqld' => { + 'socket' => '/var/lib/mysql/mysql.sock', + }, + 'mysqld-5.7' => { + 'myisam-recover-options' => :undef, + }, + 'mysqld-5.6' => { + 'myisam-recover-options' => :undef, + }, + 'mysqld-5.5' => :undef, + }, + } + end it do - expect(subject).to contain_file('mysql-config-file').with(mode: '0644', - selinux_ignore_defaults: true).with_content(%r{socket = /var/lib/mysql/mysql.sock}) + expect(subject).to contain_file('mysql-config-file') + .with_mode('0644') + .with_selinux_ignore_defaults(true) + .with_content(%r{socket = /var/lib/mysql/mysql.sock}) + end + it 'allows undef values in key/value overrides to knock keys out of default_options' do + expect(subject).to contain_file('mysql-config-file') + .without_content(%r{myisam-recover-options}) + end + it 'allows undef values in section overrides to knock sections out of default_options' do + expect(subject).to contain_file('mysql-config-file') + .without_content(%r{\[mysqld-5.5\]}) + end + it 'contains no blank lines between entries within a section' do + expect(subject).to contain_file('mysql-config-file') + .without_content(%r{\w$\R(\R)+^\w}) + end + it 'contains exactly one blank line between any two sections' do + expect(subject).to contain_file('mysql-config-file') + .without_content(%r{\w$\R\R(\R)+^\[}) end end diff --git a/templates/my.cnf.epp b/templates/my.cnf.epp index 7371164c3..dcb9140d6 100644 --- a/templates/my.cnf.epp +++ b/templates/my.cnf.epp @@ -1,25 +1,38 @@ ### MANAGED BY PUPPET ### -<% sort($options.map |$key, $value| { [$key, $value] }).map |$v| { -%> -<% if type($v[1]) =~ Type[Hash] { -%> -[<%= $v[0] %>] -<%sort($v[1].map |$key, $value| { [$key, $value] }).map |$vi| { -%> -<%- if ($vi[0] == 'ssl-disable') or ($vi[0] =~ /^ssl/ and $v[1]['ssl-disable'] == true) or ($vi[0] =~ /^ssl-/ and $v[1]['ssl'] == false) { -%> -<%- next -%> -<%- } elsif $vi[1] == true or $vi[1] == '' { -%> -<%= $vi[0] -%> -<%- } elsif type($vi[1]) =~ Type[Array] { -%> -<%- $vi[1].each |$vii| { -%> -<%-$base = $vi[0]-%> -<%= $base %> = <%= $vii %> -<%- } -%> -<%- } elsif !($vi[1] ==nil or $vi[1]=='' or $vi[1]==undef) { -%> -<%-$base = $vi[0]-%> -<%= $base %> = <%= $vi[1] -%> -<% } %> -<% } %> -<% } %> -<% } %> -<% if $includedir and $includedir != '' { -%> +<%- Array.new($options).sort.each |$section_and_contents| { + [$section, $contents] = $section_and_contents + unless $contents =~ Hash { + next + } else { -%> +[<%= $section %>] +<%- Array.new($contents).sort.each |$key_and_value| { + [$key, $value] = $key_and_value + if + # Always discard `ssl-disable`; it's a module feature, not a valid config key, and + # we never include it even if it's set to `false` + ($key == 'ssl-disable') + # If `ssl-disable` is true, discard ALL ssl-related keys, including `ssl` + or ($key =~ /^ssl/ and $contents['ssl-disable']) + # If `ssl` is specifically `false` (not unset or `undef`), discard all + # ssl-related keys EXCEPT `ssl` + or ($key =~ /^ssl-/ and $contents['ssl'] == false) + { + next + } elsif $value in [true, ''] { -%> +<%= $key %> +<%- } elsif $value =~ Array { + $value.each |$each_value| { -%> +<%= $key %> = <%= $each_value %> +<%- } + } elsif $value !~ Undef { -%> +<%= $key %> = <%= $value %> +<%- } -%> +<%# No line suppression dash below so we get a blank line at the end of each section -%> +<%- } %> +<%- } -%> +<%# No line suppression dash below so we get a second blank line before includedir -%> +<%- } %> +<%- unless $includedir.empty { -%> !includedir <%= $includedir %> -<% } -%> +<%- } -%> diff --git a/types/overrideoptions.pp b/types/overrideoptions.pp new file mode 100644 index 000000000..25e1b9946 --- /dev/null +++ b/types/overrideoptions.pp @@ -0,0 +1,6 @@ +# @summary A hash of options to merge with the default options. Sections and keys can be knocked +# out of the final config file by setting their value to `undef`. +type Mysql::OverrideOptions = Hash[ + String, + Optional[Hash], +]