diff --git a/bin/pt-archiver b/bin/pt-archiver index a5b1a4618..47e57f879 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -2489,7 +2489,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -8121,6 +8121,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --no-ascend Do not use ascending index optimization. @@ -8708,6 +8714,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 EXTENDING diff --git a/bin/pt-config-diff b/bin/pt-config-diff index 08dbc9c6c..75930bc09 100755 --- a/bin/pt-config-diff +++ b/bin/pt-config-diff @@ -2039,7 +2039,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -5813,6 +5813,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -5978,6 +5984,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index 190dad575..ab6e33d9d 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -2386,7 +2386,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -5566,6 +5566,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --numeric-ip Express IP addresses as integers. @@ -5739,6 +5745,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-duplicate-key-checker b/bin/pt-duplicate-key-checker index 381f3b30e..670c8d7db 100755 --- a/bin/pt-duplicate-key-checker +++ b/bin/pt-duplicate-key-checker @@ -873,7 +873,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -5594,6 +5594,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -5774,6 +5780,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-find b/bin/pt-find index 85a9c94d9..658fa32b5 100755 --- a/bin/pt-find +++ b/bin/pt-find @@ -265,7 +265,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -4623,6 +4623,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --or Combine tests with OR, not AND. @@ -5161,6 +5167,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index d9038ba84..a508553f4 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -1540,7 +1540,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -4563,6 +4563,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -4727,6 +4733,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-heartbeat b/bin/pt-heartbeat index 6733c0004..7230f744b 100755 --- a/bin/pt-heartbeat +++ b/bin/pt-heartbeat @@ -2991,7 +2991,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -7335,6 +7335,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -7655,6 +7661,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-index-usage b/bin/pt-index-usage index e135fa43b..fd9fb6d3a 100755 --- a/bin/pt-index-usage +++ b/bin/pt-index-usage @@ -275,7 +275,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -7326,6 +7326,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -7678,6 +7684,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-kill b/bin/pt-kill index 604e906bb..06fe29bf2 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -2043,7 +2043,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -8756,6 +8756,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --print group: Actions @@ -8844,6 +8850,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 4c3b2dfaf..d9018d372 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -2293,7 +2293,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -13439,6 +13439,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --preserve-triggers Preserves old triggers when specified. @@ -14161,6 +14167,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-query-digest b/bin/pt-query-digest index bf51c82b2..abaab823c 100755 --- a/bin/pt-query-digest +++ b/bin/pt-query-digest @@ -943,7 +943,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -16207,6 +16207,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --order-by type: Array; default: Query_time:sum @@ -16937,6 +16943,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-replica-find b/bin/pt-replica-find index c9939652a..8e0b0069b 100755 --- a/bin/pt-replica-find +++ b/bin/pt-replica-find @@ -1971,7 +1971,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -4461,6 +4461,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -4698,6 +4704,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-replica-restart b/bin/pt-replica-restart index 1b4049412..606fb3b25 100755 --- a/bin/pt-replica-restart +++ b/bin/pt-replica-restart @@ -2385,7 +2385,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -6053,6 +6053,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -6396,6 +6402,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-show-grants b/bin/pt-show-grants index d3e96ed65..f15de065c 100755 --- a/bin/pt-show-grants +++ b/bin/pt-show-grants @@ -1315,7 +1315,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -2488,6 +2488,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --only type: array @@ -2646,6 +2652,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-slave-delay b/bin/pt-slave-delay index b973bad22..7e66a8d83 100755 --- a/bin/pt-slave-delay +++ b/bin/pt-slave-delay @@ -2037,7 +2037,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 7493e347e..a94b8766e 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -1581,7 +1581,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -13784,6 +13784,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string; group: Connection @@ -14365,6 +14371,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-table-sync b/bin/pt-table-sync index 392b948e9..394362964 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -2207,7 +2207,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -12922,6 +12922,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -13332,6 +13338,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-table-usage b/bin/pt-table-usage index eeb25ca72..78fd23e99 100755 --- a/bin/pt-table-usage +++ b/bin/pt-table-usage @@ -217,7 +217,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -8385,6 +8385,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -8543,6 +8549,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-upgrade b/bin/pt-upgrade index 5b1cdc237..7aa481373 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -940,7 +940,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -11215,6 +11215,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -11479,6 +11485,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-variable-advisor b/bin/pt-variable-advisor index ee0152cfc..30ecca956 100755 --- a/bin/pt-variable-advisor +++ b/bin/pt-variable-advisor @@ -2040,7 +2040,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -6171,6 +6171,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -6337,6 +6343,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/bin/pt-visual-explain b/bin/pt-visual-explain index 849275c52..d9356b17b 100755 --- a/bin/pt-visual-explain +++ b/bin/pt-visual-explain @@ -2001,7 +2001,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } @@ -4032,6 +4032,12 @@ short form: -s; type: int Create SSL MySQL connection. +=item --mysql_ssl_optional + +short form: -o; type: int + +Disables strict SSL enforcement and makes SSL connection optional. + =item --password short form: -p; type: string @@ -4156,6 +4162,12 @@ dsn: mysql_ssl; copy: yes Create SSL connection +=item * o + +dsn: mysql_ssl_optional; copy: yes + +Disables strict SSL enforcement and makes SSL connection optional + =back =head1 ENVIRONMENT diff --git a/lib/DSNParser.pm b/lib/DSNParser.pm index c5f81ff5a..9f9ac570a 100644 --- a/lib/DSNParser.pm +++ b/lib/DSNParser.pm @@ -243,7 +243,7 @@ sub get_cxn_params { $dsn = 'DBI:mysql:' . ( $info->{D} || '' ) . ';' . join(';', map { "$opts{$_}->{dsn}=$info->{$_}" } grep { defined $info->{$_} } - qw(F h P S A s)) + qw(F h P S A s o)) . ';mysql_read_default_group=client' . ($info->{L} ? ';mysql_local_infile=1' : ''); } diff --git a/lib/Sandbox.pm b/lib/Sandbox.pm index 26fdab8ad..189fe6c4d 100644 --- a/lib/Sandbox.pm +++ b/lib/Sandbox.pm @@ -134,12 +134,7 @@ sub create_dbs { sub get_dbh_for { my ( $self, $server, $cxn_ops, $user ) = @_; _check_server($server); - if ($ENV{FORK} || "" eq 'mariadb') { - $cxn_ops ||= { AutoCommit => 1, mysql_enable_utf8 => 1, mysql_ssl => 0 }; - } - else { - $cxn_ops ||= { AutoCommit => 1, mysql_enable_utf8 => 1, mysql_ssl => 1 }; - } + $cxn_ops ||= { AutoCommit => 1, mysql_enable_utf8 => 1, mysql_ssl => 1, mysql_ssl_optional => 1 }; $user ||= 'msandbox'; PTDEBUG && _d('dbh for', $server, 'on port', $port_for{$server}); my $dp = $self->{DSNParser}; diff --git a/t/pt-archiver/ssl.t b/t/pt-archiver/ssl.t index 54de6e2bf..c378ed5d0 100644 --- a/t/pt-archiver/ssl.t +++ b/t/pt-archiver/ssl.t @@ -19,16 +19,28 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_archiver::main('--source', "F=$cnf,h=127.1,P=12345,D=sakila,t=film,u=msandbox,p=msandbox,s=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my ($output, $exit_code); -my $cnf = "/tmp/12345/my.sandbox.cnf"; - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -154,6 +166,66 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source', "F=$cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/DELETE FROM `sakila`.`film` WHERE/, + 'Queries printed with option --mysql_ssl_optional' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source=t=film', + qw(--host 127.1 --port 12345 -D sakila), + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/DELETE FROM `sakila`.`film` WHERE/, + 'Queries printed with option --mysql_ssl' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-archiver/ssl_optional.t b/t/pt-archiver/ssl_optional.t new file mode 100644 index 000000000..d8db6836e --- /dev/null +++ b/t/pt-archiver/ssl_optional.t @@ -0,0 +1,176 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-archiver"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_archiver::main('--source', "F=$cnf,h=127.1,P=12345,D=sakila,t=film,u=msandbox,p=msandbox,s=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source', "F=$cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=0", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source', "F=$cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/DELETE FROM `sakila`.`film` WHERE/, + 'Queries printed' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source=t=film', + qw(--host 127.1 --port 12345 -D sakila), + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/DELETE FROM `sakila`.`film` WHERE/, + 'Queries printed with option --mysql_ssl' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source', "F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_archiver::main('--source', "F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--no-check-charset --purge --dry-run --port 12345), + "--where", "film_id < 100") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-config-diff/ssl.t b/t/pt-config-diff/ssl.t index 46c472249..63690964a 100644 --- a/t/pt-config-diff/ssl.t +++ b/t/pt-config-diff/ssl.t @@ -20,19 +20,30 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', 'h=127.1') + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my ($output, $exit_code); -my $cnf = "/tmp/12345/my.sandbox.cnf"; - $sb->do_as_root( 'source', - q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password'/, + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, q/GRANT ALL ON sakila.* TO sha256_user@'%'/, ); @@ -145,6 +156,62 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', 'h=127.1') + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl_optional 1" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional 1' +) or diag($output); + +is( + $output, + "", + "No output when no diff" +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + 'h=127.1') + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +is( + $output, + "", + "No output when no diff and option --mysql_ssl" +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-config-diff/ssl_optional.t b/t/pt-config-diff/ssl_optional.t new file mode 100644 index 000000000..d0d72025a --- /dev/null +++ b/t/pt-config-diff/ssl_optional.t @@ -0,0 +1,166 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-config-diff"; + +require VersionParser; +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', 'h=127.1') + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0', 'h=127.1') + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', 'h=127.1') + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +is( + $output, + "", + "No output when no diff" +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_config_diff::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + 'h=127.1') + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +is( + $output, + "", + "No output when no diff and option --mysql_ssl" +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_config_diff::main("F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", 'h=127.1') + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_config_diff::main("F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", 'h=127.1') + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-deadlock-logger/ssl.t b/t/pt-deadlock-logger/ssl.t index 581985671..53f75b333 100644 --- a/t/pt-deadlock-logger/ssl.t +++ b/t/pt-deadlock-logger/ssl.t @@ -20,17 +20,29 @@ my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh1 = $sb->get_dbh_for('source', { PrintError => 0, RaiseError => 1, AutoCommit => 0 }); my $dbh2 = $sb->get_dbh_for('source', { PrintError => 0, RaiseError => 1, AutoCommit => 0 }); -if ( !$dbh1 || !$dbh2 ) { +my ($output, $exit_code); +my $dsn = $sb->dsn_for('source'); +my @args = ($dsn, qw(--iterations 1)); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_deadlock_logger::main("h=127.1,P=12345,D=sakila,t=film,u=msandbox,p=msandbox,s=1", + qw(--iterations 1) + ); + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh1 || !$dbh2 ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my ($output, $exit_code); -my $dsn = $sb->dsn_for('source'); -my @args = ($dsn, qw(--iterations 1)); - $dbh1->commit; $dbh2->commit; $sb->wipe_clean($dbh1); @@ -192,6 +204,7 @@ like( qr/127\.1.+msandbox.+GEN_CLUST_INDEX/, 'Deadlock logger prints the output with option --mysql_ssl' ) or diag($output); + ($output, $exit_code) = full_output( sub { pt_deadlock_logger::main("F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1", @@ -232,6 +245,64 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main("h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--iterations 1)); + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl_optional 1" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional 1' +) or diag($output); + +like( + $output, + qr/127\.1.+msandbox.+GEN_CLUST_INDEX/, + 'Deadlock logger prints the output with option --mysql_ssl_optional 1' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + qw(--iterations 1)); + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/127\.1.+msandbox.+GEN_CLUST_INDEX/, + 'Deadlock logger prints the output with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-deadlock-logger/ssl_optional.t b/t/pt-deadlock-logger/ssl_optional.t new file mode 100644 index 000000000..d9e2450b3 --- /dev/null +++ b/t/pt-deadlock-logger/ssl_optional.t @@ -0,0 +1,260 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-deadlock-logger"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh1 = $sb->get_dbh_for('source', { PrintError => 0, RaiseError => 1, AutoCommit => 0 }); +my $dbh2 = $sb->get_dbh_for('source', { PrintError => 0, RaiseError => 1, AutoCommit => 0 }); + +my ($output, $exit_code); +my $dsn = $sb->dsn_for('source'); +my @args = ($dsn, qw(--iterations 1)); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_deadlock_logger::main("h=127.1,P=12345,D=sakila,t=film,u=msandbox,p=msandbox,s=1", + qw(--iterations 1) + ); + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh1 || !$dbh2 ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$dbh1->commit; +$dbh2->commit; +$sb->wipe_clean($dbh1); +$sb->create_dbs($dbh1, ['test']); + +# Set up the table for creating a deadlock. +$dbh1->do("create table test.dl(a int) engine=innodb"); +$dbh1->do("insert into test.dl(a) values(0), (1)"); +$dbh1->commit; +$dbh2->commit; +$dbh1->{InactiveDestroy} = 1; +$dbh2->{InactiveDestroy} = 1; + +$dbh1->{mysql_auto_reconnect} = 1; +$dbh2->{mysql_auto_reconnect} = 1; + +sub make_deadlock { + # Fork off two children to deadlock against each other. + my %children; + foreach my $child ( 0..1 ) { + my $pid = fork(); + if ( defined($pid) && $pid == 0 ) { # I am a child + eval { + my $dbh = ($dbh1, $dbh2)[$child]; + my @stmts = ( + "set transaction isolation level serializable", + "begin", + "select * from test.dl where a = $child", + "update test.dl set a = $child where a <> $child", + ); + foreach my $stmt (@stmts[0..2]) { + $dbh->do($stmt); + } + sleep(1 + $child); + $dbh->do($stmts[-1]); + }; + if ( $EVAL_ERROR ) { + if ( $EVAL_ERROR !~ m/Deadlock found/ ) { + die $EVAL_ERROR; + } + } + exit(0); + } + elsif ( !defined($pid) ) { + die("Unable to fork for clearing deadlocks!\n"); + } + + # I already exited if I'm a child, so I'm the parent. + $children{$child} = $pid; + } + + # Wait for the children to exit. + foreach my $child ( keys %children ) { + my $pid = waitpid($children{$child}, 0); + } + eval { + $dbh1->commit; + $dbh1->disconnect(); + }; + eval { + $dbh2->commit; + $dbh2->disconnect(); + }; +} + +sub reconnect { + my $dbh = shift; + $dbh->disconnect(); + $dbh = $sb->get_dbh_for('source', { PrintError => 0, RaiseError => 1, AutoCommit => 0 }); + return $dbh; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, + q/GRANT PROCESS ON *.* TO sha256_user@'%'/, +); + +make_deadlock(); + +$dbh1 = reconnect($dbh1); +$dbh2 = reconnect($dbh2); + +# Test that there is a deadlock +$output = $dbh1->selectrow_hashref('show /*!40101 engine*/ innodb status')->{status}; +like($output, qr/WE ROLL BACK/, 'There was a deadlock'); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main("h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=0", + qw(--iterations 1)); + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main("h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--iterations 1)); + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/127\.1.+msandbox.+GEN_CLUST_INDEX/, + 'Deadlock logger prints the output' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + qw(--iterations 1)); + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/127\.1.+msandbox.+GEN_CLUST_INDEX/, + 'Deadlock logger prints the output with option --mysql_ssl' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main("F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--iterations 1)); + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_deadlock_logger::main("F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(--iterations 1)); + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$dbh1 = reconnect($dbh1); +$dbh2 = reconnect($dbh2); + +$dbh1->commit; +$dbh2->commit; +$sb->wipe_clean($dbh1); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-duplicate-key-checker/ssl.t b/t/pt-duplicate-key-checker/ssl.t index d79d9abee..9def847c3 100644 --- a/t/pt-duplicate-key-checker/ssl.t +++ b/t/pt-duplicate-key-checker/ssl.t @@ -20,18 +20,24 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my $output; +my $sample = "t/pt-duplicate-key-checker/samples/"; +my $cnf = "/tmp/12345/my.sandbox.cnf"; +my $cmd = "$trunk/bin/pt-duplicate-key-checker -F $cnf -h 127.1"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd -d mysql -t columns_priv -v P=12345,u=msandbox,p=msandbox,s=1 2>&1`; + +if ( $? != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my $output; -my $sample = "t/pt-duplicate-key-checker/samples/"; -my $cnf = "/tmp/12345/my.sandbox.cnf"; -my $cmd = "$trunk/bin/pt-duplicate-key-checker -F $cnf -h 127.1"; - $sb->wipe_clean($dbh); $sb->create_dbs($dbh, ['test']); @@ -148,6 +154,64 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +$output = `$cmd -d mysql -t columns_priv -v P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional 1" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional 1' +) or diag($output); + +# In version 8.0 order of columns in the index changed +if ($sandbox_version ge '8.0') { + like($output, + qr/PRIMARY \(`Host`,`User`,`Db`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK with option --mysql_ssl_optional 1' + ); +} else { + like($output, + qr/PRIMARY \(`Host`,`Db`,`User`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK with option --mysql_ssl_optional 1' + ); +} + +$output = `$cmd -d mysql -t columns_priv -v --host 127.1 --port 12345 --user sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl=1 and --mysql_ssl_optional=1" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl=1 and --mysql_ssl_optional=1' +) or diag($output); + +# In version 8.0 order of columns in the index changed +if ($sandbox_version ge '8.0') { + like($output, + qr/PRIMARY \(`Host`,`User`,`Db`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK with option --mysql_ssl=1 and --mysql_ssl_optional=1' + ); +} else { + like($output, + qr/PRIMARY \(`Host`,`Db`,`User`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PKi with option --mysql_ssl=1 and --mysql_ssl_optional=1' + ); +} + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-duplicate-key-checker/ssl_optional.t b/t/pt-duplicate-key-checker/ssl_optional.t new file mode 100644 index 000000000..51cf8a26e --- /dev/null +++ b/t/pt-duplicate-key-checker/ssl_optional.t @@ -0,0 +1,164 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-duplicate-key-checker"; + +require VersionParser; +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my $output; +my $sample = "t/pt-duplicate-key-checker/samples/"; +my $cnf = "/tmp/12345/my.sandbox.cnf"; +my $cmd = "$trunk/bin/pt-duplicate-key-checker -F $cnf -h 127.1"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd -d mysql -t columns_priv -v P=12345,u=msandbox,p=msandbox,s=1 2>&1`; + +if ( $? == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->wipe_clean($dbh); +$sb->create_dbs($dbh, ['test']); + +my $transform_int = undef; +# In version 8.0 integer display width is deprecated and not shown in the outputs. +# So we need to transform our samples. +if ($sandbox_version ge '8.0') { + $transform_int = sub { + my $txt = slurp_file(shift); + $txt =~ s/int\(\d{1,2}\)/int/g; + print $txt; + }; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON mysql.* TO sha256_user@'%'/, +); + +$output = `$cmd -d mysql -t columns_priv -v P=12345,u=sha256_user,p=sha256_user%password,s=0 2>&1`; + +isnt( + $?, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +$output = `$cmd -d mysql -t columns_priv -v P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +# In version 8.0 order of columns in the index changed +if ($sandbox_version ge '8.0') { + like($output, + qr/PRIMARY \(`Host`,`User`,`Db`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK' + ); +} else { + like($output, + qr/PRIMARY \(`Host`,`Db`,`User`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK' + ); +} + +$output = `$cmd -d mysql -t columns_priv -v --host 127.1 --port 12345 --user sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl=1 --mysql_ssl_optional=1" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl=1 --mysql_ssl_optional=1' +) or diag($output); + +# In version 8.0 order of columns in the index changed +if ($sandbox_version ge '8.0') { + like($output, + qr/PRIMARY \(`Host`,`User`,`Db`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PK with option --mysql_ssl=1 --mysql_ssl_optional=1' + ); +} else { + like($output, + qr/PRIMARY \(`Host`,`Db`,`User`,`Table_name`,`Column_name`\)/, + 'Finds mysql.columns_priv PKi with option --mysql_ssl=1 --mysql_ssl_optional=1' + ); +} + +$output = `$cmd -d mysql -t columns_priv -v F=t/pt-archiver/samples/pt-191.cnf,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 2>&1`; + +is( + $?, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +$output = `$cmd -d mysql -t columns_priv -v F=t/pt-archiver/samples/pt-191-error.cnf,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 2>&1`; + +isnt( + $?, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-find/ssl.t b/t/pt-find/ssl.t index eee18d4f4..8740d14d5 100644 --- a/t/pt-find/ssl.t +++ b/t/pt-find/ssl.t @@ -20,17 +20,23 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my $output; +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-find"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=msandbox --password=msandbox --mysql_ssl=1 2>&1`; + +if ( $? != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my $output; -my $cnf = '/tmp/12345/my.sandbox.cnf'; -my $cmd = "$trunk/bin/pt-find"; - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -48,7 +54,7 @@ isnt( like( $output, qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, - 'No secure connection error raised when SSL connection used' + 'Secure connection error raised when no SSL connection used' ) or diag($output); $output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 2>&1`; @@ -62,7 +68,7 @@ is( unlike( $output, qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, - 'Secure connection error raised when no SSL connection used' + 'No secure connection error raised when SSL connection used' ) or diag($output); like($output, qr/`mysql`.`columns_priv`/, 'Found mysql.columns_priv'); @@ -121,6 +127,49 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 2>&1`; + +is( + $?, + 0, + "Error not raised when SSL connection is used with mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error raised when SSL connection used with mysql_ssl_optional' +) or diag($output); + +like($output, qr/`mysql`.`columns_priv`/, 'Found mysql.columns_priv with mysql_ssl_optional'); + +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 --exec-dsn=h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --exec-plus "INSERT INTO test.pt_find_ssl() SELECT COUNT(*) FROM %s" 2>&1`; + +is( + $?, + 0, + "Error not raised when SSL connection is used with DSN and mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error raised when SSL connection used with DSN and mysql_ssl_optional' +) or diag($output); + +$output = `/tmp/12346/use -N -e "SELECT COUNT(*) FROM test.pt_find_ssl"`; +chomp($output); + +is( + $output, + 2, + 'DSN option s works with pt-find and mysql_ssl_optional' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-find/ssl_optional.t b/t/pt-find/ssl_optional.t new file mode 100644 index 000000000..99ee0e4ff --- /dev/null +++ b/t/pt-find/ssl_optional.t @@ -0,0 +1,138 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-find"; + +require VersionParser; +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my $output; +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-find"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=msandbox --password=msandbox --mysql_ssl=1 2>&1`; + +if ( $? == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON *.* TO sha256_user@'%'/, +); + +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=0 2>&1`; + +isnt( + $?, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 2>&1`; + +is( + $?, + 0, + "Error not raised when SSL connection is used" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error raised when SSL connection used' +) or diag($output); + +like($output, qr/`mysql`.`columns_priv`/, 'Found mysql.columns_priv'); + +$dbh->do('CREATE DATABASE IF NOT EXISTS test'); +$dbh->do('CREATE TABLE test.pt_find_ssl(cnt INT)'); + +$output = `$cmd -F $cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 --exec-dsn=h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --exec-plus "INSERT INTO test.pt_find_ssl() SELECT COUNT(*) FROM %s" 2>&1`; + +is( + $?, + 0, + "Error not raised when SSL connection is used with DSN" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error raised when SSL connection used with DSN' +) or diag($output); + +$output = `/tmp/12346/use -N -e "SELECT COUNT(*) FROM test.pt_find_ssl"`; +chomp($output); + +is( + $output, + 1, + 'DSN option s works with pt-find' +) or diag($output); + +$output = `$cmd -F t/pt-archiver/samples/pt-191.cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 2>&1`; + +is( + $?, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +$output = `$cmd -F t/pt-archiver/samples/pt-191-error.cnf --host=127.0.0.1 --port=12345 mysql --tblregex column --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 2>&1`; + +isnt( + $?, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; +exit; diff --git a/t/pt-fk-error-logger/ssl.t b/t/pt-fk-error-logger/ssl.t index c7b234436..5daedae02 100644 --- a/t/pt-fk-error-logger/ssl.t +++ b/t/pt-fk-error-logger/ssl.t @@ -21,7 +21,22 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-fk-error-logger -F $cnf "; +my @args = qw(--iterations 1); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_fk_error_logger::main(@args, 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1'), + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { @@ -30,11 +45,6 @@ elsif ( $sandbox_version lt '8.0' ) { $sb->create_dbs($dbh, [qw(test)]); -my ($output, $exit_code); -my $cnf = '/tmp/12345/my.sandbox.cnf'; -my $cmd = "$trunk/bin/pt-fk-error-logger -F $cnf "; -my @args = qw(--iterations 1); - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -160,6 +170,62 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'), + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/Foreign key constraint fails/, + "Prints fk error by default with option mysql_ssl_optional" +); + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'h=127.1', + qw(--port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1)) + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option mysql_ssl and mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option mysql_ssl and mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/Foreign key constraint fails/, + "Prints fk error by default with option mysql_ssl and mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-fk-error-logger/ssl_optional.t b/t/pt-fk-error-logger/ssl_optional.t new file mode 100644 index 000000000..0a2e9e995 --- /dev/null +++ b/t/pt-fk-error-logger/ssl_optional.t @@ -0,0 +1,180 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Time::HiRes qw(sleep); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-fk-error-logger"; + +require VersionParser; +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-fk-error-logger -F $cnf "; +my @args = qw(--iterations 1); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_fk_error_logger::main(@args, 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1'), + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->create_dbs($dbh, [qw(test)]); + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON test.* TO sha256_user@'%'/, + q/GRANT PROCESS ON *.* TO sha256_user@'%'/, +); + +$sb->load_file('source', 't/pt-fk-error-logger/samples/fke_tbl.sql', 'test'); + +# ######################################################################### +# Test saving foreign key errors to --dest. +# ######################################################################### + +# First, create a foreign key error. +`/tmp/12345/use -D test < $trunk/t/pt-fk-error-logger/samples/fke.sql 1>/dev/null 2>/dev/null`; + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0'), + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'), + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/Foreign key constraint fails/, + "Prints fk error by default" +); + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'h=127.1', + qw(--port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1)) + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option mysql_ssl' +) or diag($output); + +like( + $output, + qr/Foreign key constraint fails/, + "Prints fk error by default with option mysql_ssl" +); + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'), + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_fk_error_logger::main(@args, 'F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'), + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-heartbeat/ssl.t b/t/pt-heartbeat/ssl.t index 22582f573..fcf10ab19 100644 --- a/t/pt-heartbeat/ssl.t +++ b/t/pt-heartbeat/ssl.t @@ -20,7 +20,22 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-heartbeat -F $cnf "; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1", + qw(-D test --check)), + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { @@ -29,10 +44,6 @@ elsif ( $sandbox_version lt '8.0' ) { $sb->create_dbs($dbh, ['test']); -my ($output, $exit_code); -my $cnf = '/tmp/12345/my.sandbox.cnf'; -my $cmd = "$trunk/bin/pt-heartbeat -F $cnf "; - $dbh->do('drop table if exists test.heartbeat'); $dbh->do(q{CREATE TABLE test.heartbeat ( id int NOT NULL PRIMARY KEY, @@ -152,6 +163,62 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(-D test --check)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option mysql_ssl_optional' +) or diag($output); + +$row = $dbh->selectall_hashref('select * from test.heartbeat', 'id'); +is( + $row->{1}->{id}, + 1, + "Automatically inserts heartbeat row (issue 1292) with option mysql_ssl_optional" +); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + qw(-D test --check)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +$row = $dbh->selectall_hashref('select * from test.heartbeat', 'id'); +is( + $row->{1}->{id}, + 1, + "Automatically inserts heartbeat row (issue 1292) with option --mysql_ssl and --mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-heartbeat/ssl_optional.t b/t/pt-heartbeat/ssl_optional.t new file mode 100644 index 000000000..394b955eb --- /dev/null +++ b/t/pt-heartbeat/ssl_optional.t @@ -0,0 +1,175 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; +use Data::Dumper; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-heartbeat"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-heartbeat -F $cnf "; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1", + qw(-D test --check)), + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->create_dbs($dbh, ['test']); + +$dbh->do('drop table if exists test.heartbeat'); +$dbh->do(q{CREATE TABLE test.heartbeat ( + id int NOT NULL PRIMARY KEY, + ts datetime NOT NULL + ) ENGINE=MEMORY}); +$sb->wait_for_replicas; + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON test.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0", + qw(-D test --check)) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(-D test --check)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +my $row = $dbh->selectall_hashref('select * from test.heartbeat', 'id'); +is( + $row->{1}->{id}, + 1, + "Automatically inserts heartbeat row (issue 1292)" +); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main( + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + qw(-D test --check)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +$row = $dbh->selectall_hashref('select * from test.heartbeat', 'id'); +is( + $row->{1}->{id}, + 1, + "Automatically inserts heartbeat row (issue 1292) with option --mysql_ssl" +); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(-D test --check)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + qw(-D test --check)) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); + +done_testing; +exit; diff --git a/t/pt-index-usage/ssl.t b/t/pt-index-usage/ssl.t index 9db86c489..e86e1f044 100644 --- a/t/pt-index-usage/ssl.t +++ b/t/pt-index-usage/ssl.t @@ -20,7 +20,25 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my @args = ('-F', $cnf); +my $samples = "t/pt-index-usage/samples/"; +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=msandbox --password=msandbox --mysql_ssl=1), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { @@ -30,11 +48,6 @@ elsif ( !@{ $dbh->selectall_arrayref("show databases like 'sakila'") } ) { plan skip_all => "Sakila database is not loaded"; } -my $cnf = '/tmp/12345/my.sandbox.cnf'; -my @args = ('-F', $cnf); -my $samples = "t/pt-index-usage/samples/"; -my ($output, $exit_code); - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -182,6 +195,64 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +@args = ('-F', $cnf); + +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional 1 --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional 1 --mysql_ssl' +) or diag($output); + +like( + $output, + qr/ALTER TABLE `sakila`.`film_text` DROP KEY `idx_title_description`; -- type:non-unique/, + 'A simple query that does not use any indexes with option --mysql_ssl_optional 1 --mysql_ssl', +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1), + qw(--create-save-results-database), + '--save-results-database=h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1,D=test', + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password via DSN with option --mysql_ssl_optional 1" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with DSN with option --mysql_ssl_optional 1' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-index-usage/ssl_optional.t b/t/pt-index-usage/ssl_optional.t new file mode 100644 index 000000000..96bbb7c46 --- /dev/null +++ b/t/pt-index-usage/ssl_optional.t @@ -0,0 +1,206 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +require "$trunk/bin/pt-index-usage"; +require VersionParser; + +use Sandbox; +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my @args = ('-F', $cnf); +my $samples = "t/pt-index-usage/samples/"; +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=msandbox --password=msandbox --mysql_ssl=1), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} +elsif ( !@{ $dbh->selectall_arrayref("show databases like 'sakila'") } ) { + plan skip_all => "Sakila database is not loaded"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, + q/GRANT ALL ON test.* TO sha256_user@'%'/, +); + +# This query doesn't use indexes so there's an unused PK and +# an unused secondary index. Only the secondary index should +# be printed since dropping PKs is not suggested by default. + +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=0), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/ALTER TABLE `sakila`.`film_text` DROP KEY `idx_title_description`; -- type:non-unique/, + 'A simple query that does not use any indexes', +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + qw(--create-save-results-database), + '--save-results-database=h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1,D=test', + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password via DSN" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with DSN' +) or diag($output); + +$output = `/tmp/12345/use -N -e "SHOW TABLES FROM test"`; + +my $expected = < 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +@args = ('-F', "$trunk/t/pt-archiver/samples/pt-191-error.cnf"); +($output, $exit_code) = full_output( + sub { + pt_index_usage::main( + @args, + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1), + "$trunk/$samples/slow001.txt") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; +exit; diff --git a/t/pt-kill/ssl.t b/t/pt-kill/ssl.t index 3e4422bc4..785dba0c4 100644 --- a/t/pt-kill/ssl.t +++ b/t/pt-kill/ssl.t @@ -23,20 +23,26 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $source_dbh = $sb->get_dbh_for('source'); -if ( !$source_dbh ) { +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-kill"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --busy-time 1s --print --run-time 1 2>&1`; + +if ( $? != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } else { - plan tests => 13; + plan tests => 17; } -my ($output, $exit_code); -my $cnf = '/tmp/12345/my.sandbox.cnf'; -my $cmd = "$trunk/bin/pt-kill"; - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -153,6 +159,39 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); + +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +$output = `$cmd F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --busy-time 1s --print --run-time 10 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional (short form -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short form -o)' +) or diag($output); + +$output = `$cmd F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password --mysql_ssl=1 --busy-time 1s --print --run-time 10 --mysql_ssl_optional 1 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-kill/ssl_optional.t b/t/pt-kill/ssl_optional.t new file mode 100644 index 000000000..c87cfda39 --- /dev/null +++ b/t/pt-kill/ssl_optional.t @@ -0,0 +1,170 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; + $ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use Data::Dumper; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-kill"; +require VersionParser; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $source_dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-kill"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$cmd F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --busy-time 1s --print --run-time 1 2>&1`; + +if ( $? == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} +else { + plan tests => 13; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT PROCESS ON *.* TO sha256_user@'%'/, +); + +$output = `$cmd F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0 --busy-time 1s --print --run-time 10 2>&1`; + +isnt( + $?, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +# Shell out to a sleep(10) query and try to capture the query. +# Backticks don't work here. +system("/tmp/12345/use -e 'select sleep(5)' >/dev/null &"); + +$output = `$cmd F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --busy-time 1s --print --run-time 10 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +# $output ought to be something like +# 2009-05-27T22:19:40 KILL 5 (Query 1 sec) select sleep(10) +# 2009-05-27T22:19:41 KILL 5 (Query 2 sec) select sleep(10) +# 2009-05-27T22:19:42 KILL 5 (Query 3 sec) select sleep(10) +# 2009-05-27T22:19:43 KILL 5 (Query 4 sec) select sleep(10) +# 2009-05-27T22:19:44 KILL 5 (Query 5 sec) select sleep(10) +# 2009-05-27T22:19:45 KILL 5 (Query 6 sec) select sleep(10) +# 2009-05-27T22:19:46 KILL 5 (Query 7 sec) select sleep(10) +# 2009-05-27T22:19:47 KILL 5 (Query 8 sec) select sleep(10) +# 2009-05-27T22:19:48 KILL 5 (Query 9 sec) select sleep(10) +my @times = $output =~ m/\(Query (\d+) sec\)/g; +ok( + @times > 2 && @times < 7, + "There were 2 to 5 captures" +) or diag($output); + +# Shell out to a sleep(10) query and try to capture the query. +# Backticks don't work here. +system("/tmp/12345/use -e 'select sleep(5)' >/dev/null &"); + +$output = `$cmd --host 127.1 --port 12345 --user sha256_user --password=sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1 --busy-time 1s --print --run-time 10 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +# $output ought to be something like +# 2009-05-27T22:19:40 KILL 5 (Query 1 sec) select sleep(10) +# 2009-05-27T22:19:41 KILL 5 (Query 2 sec) select sleep(10) +# 2009-05-27T22:19:42 KILL 5 (Query 3 sec) select sleep(10) +# 2009-05-27T22:19:43 KILL 5 (Query 4 sec) select sleep(10) +# 2009-05-27T22:19:44 KILL 5 (Query 5 sec) select sleep(10) +# 2009-05-27T22:19:45 KILL 5 (Query 6 sec) select sleep(10) +# 2009-05-27T22:19:46 KILL 5 (Query 7 sec) select sleep(10) +# 2009-05-27T22:19:47 KILL 5 (Query 8 sec) select sleep(10) +# 2009-05-27T22:19:48 KILL 5 (Query 9 sec) select sleep(10) +@times = $output =~ m/\(Query (\d+) sec\)/g; +ok( + @times > 2 && @times < 7, + "There were 2 to 5 captures with option --mysql_ssl" +) or diag($output); + +$output = `$cmd F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --busy-time 1s --print --run-time 10 2>&1`; + +is( + $?, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +$output = `$cmd F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --busy-time 1s --print --run-time 10 2>&1`; + +isnt( + $?, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($source_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/t/pt-online-schema-change/option_sanity.t b/t/pt-online-schema-change/option_sanity.t index d53e5b7cd..10d34dd40 100644 --- a/t/pt-online-schema-change/option_sanity.t +++ b/t/pt-online-schema-change/option_sanity.t @@ -57,6 +57,12 @@ like( "--statistics is FALSE by default" ); +like( + $output, + qr/--mysql_ssl_optional/, + "--mysql_ssl_optional option exists in help" +); + $output = `$cmd h=127.1,P=12345,u=msandbox,p=msandbox --alter-foreign-keys-method drop_swap --no-drop-new-table`; like( $output, diff --git a/t/pt-online-schema-change/samples/ssl_dsns.sql b/t/pt-online-schema-change/samples/ssl_dsns.sql index b91cd0716..5ddde9251 100644 --- a/t/pt-online-schema-change/samples/ssl_dsns.sql +++ b/t/pt-online-schema-change/samples/ssl_dsns.sql @@ -8,6 +8,6 @@ CREATE TABLE `dsns` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -INSERT INTO `dsns` VALUES (1, NULL, "F=/home/sveta/src/percona/percona-toolkit/t/pt-archiver/samples/pt-191-replica1.cnf,P=12346,h=127.0.0.1,u=root,p=msandbox,s=1"); -INSERT INTO `dsns` VALUES (2, NULL, "F=/home/sveta/src/percona/percona-toolkit/t/pt-archiver/samples/pt-191-replica2.cnf,P=12347,h=127.0.0.1,u=root,p=msandbox,s=1"); +INSERT INTO `dsns` VALUES (1, NULL, "F=t/pt-archiver/samples/pt-191-replica1.cnf,P=12346,h=127.0.0.1,u=root,p=msandbox,s=1"); +INSERT INTO `dsns` VALUES (2, NULL, "F=t/pt-archiver/samples/pt-191-replica2.cnf,P=12347,h=127.0.0.1,u=root,p=msandbox,s=1"); diff --git a/t/pt-online-schema-change/ssl.t b/t/pt-online-schema-change/ssl.t index 584d0a428..fe5736461 100644 --- a/t/pt-online-schema-change/ssl.t +++ b/t/pt-online-schema-change/ssl.t @@ -22,16 +22,6 @@ my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $source_dbh = $sb->get_dbh_for('source'); my $replica_dbh = $sb->get_dbh_for('replica1'); -if ( !$source_dbh ) { - plan skip_all => 'Cannot connect to sandbox source'; -} -elsif ( !$replica_dbh ) { - plan skip_all => 'Cannot connect to sandbox replica1'; -} -elsif ( $sandbox_version lt '8.0' ) { - plan skip_all => "Requires MySQL 8.0 or newer"; -} - # The sandbox servers run with lock_wait_timeout=3 and it's not dynamic # so we need to specify --set-vars innodb_lock_wait_timeout=3 else the # tool will die. @@ -41,6 +31,30 @@ my $output; my $exit_code; my $sample = "t/pt-online-schema-change/samples/"; +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=sakila,t=actor,u=msandbox,p=msandbox,s=1", + "--alter", "force", + "--alter-foreign-keys-method", "auto", + qw(--dry-run --no-check-alter)), + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( !$replica_dbh ) { + plan skip_all => 'Cannot connect to sandbox replica1'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -179,6 +193,57 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +# Restoring environment for the new test +$sb->load_file('source', "$sample/del-trg-bug-1103672.sql"); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=test,t=t1,u=sha256_user,p=sha256_user%password,s=1,o=1", + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, +); + +is( + $exit_code, + 0, + "No error when using mysql_ssl_optional DSN parameter (o=1)" +) or diag($output); + +like( + $output, + qr/Successfully altered `test`.`t1`/, + "DROP PRIMARY KEY with mysql_ssl_optional DSN parameter" +); + +# Restoring environment for the new test +$sb->load_file('source', "$sample/del-trg-bug-1103672.sql"); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=test,t=t1", + qw(--user sha256_user --password sha256_user%password --mysql_ssl_optional 1 --mysql_ssl 1), + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, +); + +is( + $exit_code, + 0, + "No error when using --mysql_ssl_optional option" +) or diag($output); + +like( + $output, + qr/Successfully altered `test`.`t1`/, + "DROP PRIMARY KEY with --mysql_ssl_optional option" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-online-schema-change/ssl_optional.t b/t/pt-online-schema-change/ssl_optional.t new file mode 100644 index 000000000..2c999a38e --- /dev/null +++ b/t/pt-online-schema-change/ssl_optional.t @@ -0,0 +1,203 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use Data::Dumper; +use PerconaTest; +use Sandbox; + +require "$trunk/bin/pt-online-schema-change"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $source_dbh = $sb->get_dbh_for('source'); +my $replica_dbh = $sb->get_dbh_for('replica1'); + +# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic +# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the +# tool will die. +my $source_dsn = 'h=127.1,P=12345'; +my @args = (qw(--set-vars innodb_lock_wait_timeout=3)); +my $output; +my $exit_code; +my $sample = "t/pt-online-schema-change/samples/"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=sakila,t=actor,u=msandbox,p=msandbox,s=1", + "--alter", "force", + "--alter-foreign-keys-method", "auto", + qw(--dry-run --no-check-alter)), + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( !$replica_dbh ) { + plan skip_all => 'Cannot connect to sandbox replica1'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON test.* TO sha256_user@'%'/, + q/GRANT SELECT ON test_ssl.* TO sha256_user@'%'/, + q/GRANT REPLICATION SLAVE ON *.* TO sha256_user@'%'/, + q/GRANT SUPER ON *.* TO sha256_user@'%'/, +); + +# ############################################################################# +# DROP PRIMARY KEY +# ############################################################################# + +$sb->load_file('source', "$sample/del-trg-bug-1103672.sql"); +$sb->load_file('source', "$sample/ssl_dsns.sql"); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=test,t=t1,u=sha256_user,p=sha256_user%password,s=0", + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=test,t=t1,u=sha256_user,p=sha256_user%password,s=1,o=1", + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/Successfully altered `test`.`t1`/, + "DROP PRIMARY KEY" +); + +# Restoring environment for the new test +$sb->load_file('source', "$sample/del-trg-bug-1103672.sql"); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,D=test,t=t1", + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/Successfully altered `test`.`t1`/, + "DROP PRIMARY KEY with option --mysql_ssl" +); + +# Restoring environment for the new test +$sb->load_file('source', "$sample/del-trg-bug-1103672.sql"); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "$source_dsn,F=t/pt-archiver/samples/pt-191.cnf,D=test,t=t1,u=sha256_user,p=sha256_user%password,s=1,o=1", + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter), + "--recursion-method=dsn=F=t/pt-archiver/samples/pt-191.cnf,D=test_ssl,t=dsns,h=127.0.0.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1"), + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_online_schema_change::main(@args, + "F=$trunk/t/pt-archiver/samples/pt-191-error.cnf,$source_dsn,D=test,t=t1,u=sha256_user,p=sha256_user%password,s=1,o=1", + "--alter", "drop primary key, add column _id int unsigned not null primary key auto_increment FIRST", + qw(--execute --no-check-alter)), + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($source_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-query-digest/ssl.t b/t/pt-query-digest/ssl.t index 4654974c4..519943015 100644 --- a/t/pt-query-digest/ssl.t +++ b/t/pt-query-digest/ssl.t @@ -21,17 +21,27 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; +my $samples = "$trunk/t/pt-query-digest/samples"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_query_digest::main("--explain=F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1", + "$samples/slow028.txt") }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my ($output, $exit_code); -my $cnf = "/tmp/12345/my.sandbox.cnf"; -my $samples = "$trunk/t/pt-query-digest/samples"; - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -151,6 +161,63 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain='F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'", + "$samples/slow028.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with mysql_ssl_optional (short form -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with mysql_ssl_optional (short form -o)' +) or diag($output); + +like( + $output, + qr/Query size 24 24 24 24 24 0 24/, + 'Analysis printed with mysql_ssl_optional (short form -o)' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain=h=127.1,P=12345,u=sha256_user,p=sha256_user%password", + qw(--mysql_ssl 1 --mysql_ssl_optional 1), + "$samples/slow028.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with options --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with options --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/Query size 24 24 24 24 24 0 24/, + 'Analysis printed with options --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-query-digest/ssl_optional.t b/t/pt-query-digest/ssl_optional.t new file mode 100644 index 000000000..e3ee22aeb --- /dev/null +++ b/t/pt-query-digest/ssl_optional.t @@ -0,0 +1,171 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; + +require "$trunk/bin/pt-query-digest"; +require VersionParser; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = "/tmp/12345/my.sandbox.cnf"; +my $samples = "$trunk/t/pt-query-digest/samples"; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_query_digest::main("--explain=F=$cnf,h=127.1,P=12345,u=msandbox,p=msandbox,s=1", + "$samples/slow028.txt") }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain=F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0", + "$samples/slow028.txt") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain='F=$cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1'", + "$samples/slow028.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/Query size 24 24 24 24 24 0 24/, + 'Analysis printed' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain=h=127.1,P=12345,u=sha256_user,p=sha256_user%password", + qw(--mysql_ssl 1 --mysql_ssl_optional=1), + "$samples/slow028.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/Query size 24 24 24 24 24 0 24/, + 'Analysis printed with option --mysql_ssl' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain=F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + "$samples/slow028.txt") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_query_digest::main("--explain=F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1", + "$samples/slow028.txt") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-replica-find/ssl.t b/t/pt-replica-find/ssl.t index b9e92cbb3..ac23612b0 100644 --- a/t/pt-replica-find/ssl.t +++ b/t/pt-replica-find/ssl.t @@ -26,17 +26,13 @@ my $replica1_dbh = $sb->get_dbh_for('replica1'); my $replica2_dbh = $sb->get_dbh_for('replica2'); my $output; -# This test is sensitive to ghost/old replicas created/destroyed by other -# tests. So we stop the replicas, restart the source, and start everything -# again. Hopefully this will return the env to its original state. -$replica2_dbh->do("STOP ${replica_name}"); -$replica1_dbh->do("STOP ${replica_name}"); -diag(`/tmp/12345/stop >/dev/null`); -diag(`/tmp/12345/start >/dev/null`); -$replica1_dbh->do("START ${replica_name}"); -$replica2_dbh->do("START ${replica_name}"); +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$trunk/bin/pt-replica-find h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --report-format hostname 2>&1`; -if ( !$source_dbh ) { +if ( $? != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( !$replica1_dbh ) { @@ -46,6 +42,16 @@ elsif ( !$replica2_dbh ) { plan skip_all => 'Cannot connect to second sandbox replica'; } +# This test is sensitive to ghost/old replicas created/destroyed by other +# tests. So we stop the replicas, restart the source, and start everything +# again. Hopefully this will return the env to its original state. +$replica2_dbh->do("STOP ${replica_name}"); +$replica1_dbh->do("STOP ${replica_name}"); +diag(`/tmp/12345/stop >/dev/null`); +diag(`/tmp/12345/start >/dev/null`); +$replica1_dbh->do("START ${replica_name}"); +$replica2_dbh->do("START ${replica_name}"); + $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -143,6 +149,58 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +$output = `$trunk/bin/pt-replica-find h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --report-format hostname 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with mysql_ssl_optional (short form -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with mysql_ssl_optional (short form -o)' +) or diag($output); + +$expected = <&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with options --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with options --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +$expected = < 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-replica-find"; + +if ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $source_dbh = $sb->get_dbh_for('source'); +my $replica1_dbh = $sb->get_dbh_for('replica1'); +my $replica2_dbh = $sb->get_dbh_for('replica2'); +my $output; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$trunk/bin/pt-replica-find h=127.1,P=12345,u=msandbox,p=msandbox,s=1 --report-format hostname 2>&1`; + +if ( $? == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( !$replica1_dbh ) { + plan skip_all => 'Cannot connect to sandbox replica'; +} +elsif ( !$replica2_dbh ) { + plan skip_all => 'Cannot connect to second sandbox replica'; +} + +# This test is sensitive to ghost/old replicas created/destroyed by other +# tests. So we stop the replicas, restart the source, and start everything +# again. Hopefully this will return the env to its original state. +$replica2_dbh->do("STOP ${replica_name}"); +$replica1_dbh->do("STOP ${replica_name}"); +diag(`/tmp/12345/stop >/dev/null`); +diag(`/tmp/12345/start >/dev/null`); +$replica1_dbh->do("START ${replica_name}"); +$replica2_dbh->do("START ${replica_name}"); + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT REPLICATION SLAVE, PROCESS ON *.* TO sha256_user@'%'/, +); + +# Start an instance +$output = `$trunk/bin/pt-replica-find h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0 --report-format hostname 2>&1`; + +isnt( + $?, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +$output = `$trunk/bin/pt-replica-find h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --report-format hostname 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +my $expected = <&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +$expected = <&1`; + +is( + $?, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +$output = `$trunk/bin/pt-replica-find F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 --report-format hostname --recurse 0 2>&1`; + +isnt( + $?, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-replica-restart/ssl.t b/t/pt-replica-restart/ssl.t index cda32f44a..c6f35d17a 100644 --- a/t/pt-replica-restart/ssl.t +++ b/t/pt-replica-restart/ssl.t @@ -19,6 +19,15 @@ if ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } +my $output; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 h=127.1,P=12346,u=msandbox,p=msandbox,s=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +if ( $? != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} + diag('Restarting the sandbox'); diag(`SAKILA=0 REPLICATION_THREADS=0 GTID=1 $trunk/sandbox/test-env restart`); diag("Sandbox restarted"); @@ -27,7 +36,6 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $source_dbh = $sb->get_dbh_for('source'); my $replica_dbh = $sb->get_dbh_for('replica1'); -my $output; if ( !$source_dbh ) { plan skip_all => 'Cannot connect to sandbox source'; @@ -143,6 +151,50 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password and option --mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +unlike( + $output, + qr/Error does not match/, + '--error-text works (issue 459) with option --mysql_ssl_optional (short version -o)' +); + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 --host=127.1 --port=12346 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with options --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with options --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +unlike( + $output, + qr/Error does not match/, + '--error-text works (issue 459) with options --mysql_ssl and --mysql_ssl_optional' +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-replica-restart/ssl_optional.t b/t/pt-replica-restart/ssl_optional.t new file mode 100644 index 000000000..73a65074b --- /dev/null +++ b/t/pt-replica-restart/ssl_optional.t @@ -0,0 +1,162 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-replica-restart"; + +if ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +my $output; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 h=127.1,P=12346,u=msandbox,p=msandbox,s=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +if ( $? == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} + +diag('Restarting the sandbox'); +diag(`SAKILA=0 REPLICATION_THREADS=0 GTID=1 $trunk/sandbox/test-env restart`); +diag("Sandbox restarted"); + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $source_dbh = $sb->get_dbh_for('source'); +my $replica_dbh = $sb->get_dbh_for('replica1'); + +if ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( !$replica_dbh ) { + plan skip_all => 'Cannot connect to sandbox replica'; +} + +$source_dbh->do('DROP DATABASE IF EXISTS test'); +$source_dbh->do('CREATE DATABASE test'); +$source_dbh->do('CREATE TABLE test.t (a INT)'); +$sb->wait_for_replicas; + +# Bust replication +$source_dbh->do('DROP TABLE IF EXISTS test.t'); +$source_dbh->do('CREATE TABLE test.t (a INT)'); +sleep 1; +$replica_dbh->do('DROP TABLE test.t'); +$source_dbh->do('INSERT INTO test.t SELECT 1'); +$output = `/tmp/12346/use -e "show ${replica_name} status"`; +like( + $output, + qr/Table 'test.t' doesn't exist'/, + 'It is busted' +); + +$sb->do_as_root( + 'replica1', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT REPLICATION SLAVE, PROCESS ON *.* TO sha256_user@'%'/, +); + +# Start an instance +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=0 --error-text "doesn't exist" --run-time 1s 2>&1`; + +isnt( + $?, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +unlike( + $output, + qr/Error does not match/, + '--error-text works (issue 459)' +); + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 --host=127.1 --port=12346 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +is( + $?, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +unlike( + $output, + qr/Error does not match/, + '--error-text works (issue 459) with option --mysql_ssl' +); + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 F=t/pt-archiver/samples/pt-191-replica1.cnf,h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +is( + $?, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +$output = `$trunk/bin/pt-replica-restart --max-sleep 0.25 F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12346,u=sha256_user,p=sha256_user%password,s=1,o=1 --error-text "doesn't exist" --run-time 1s 2>&1`; + +isnt( + $?, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('replica1', q/DROP USER 'sha256_user'@'%'/); + +diag(`rm -f /tmp/pt-replica-re*`); +diag(`$trunk/sandbox/test-env restart`); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-show-grants/ssl.t b/t/pt-show-grants/ssl.t index a9b0fe81c..32f5c8594 100644 --- a/t/pt-show-grants/ssl.t +++ b/t/pt-show-grants/ssl.t @@ -21,7 +21,23 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { @@ -30,9 +46,6 @@ elsif ( $sandbox_version lt '8.0' ) { $sb->wipe_clean($dbh); -my ($output, $exit_code); -my $cnf = '/tmp/12345/my.sandbox.cnf'; - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -158,6 +171,65 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option mysql_ssl_optional (short version -o)' +) or diag($output); + +like( + $output, + qr/Grants dumped by/, + 'It lives with option mysql_ssl_optional (short version -o)', +); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with options --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with options --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/Grants dumped by/, + 'It lives with options --mysql_ssl and --mysql_ssl_optional', +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-show-grants/ssl_optional.t b/t/pt-show-grants/ssl_optional.t new file mode 100644 index 000000000..fd3ff6764 --- /dev/null +++ b/t/pt-show-grants/ssl_optional.t @@ -0,0 +1,181 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +use SqlModes; +require "$trunk/bin/pt-show-grants"; +require VersionParser; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->wipe_clean($dbh); + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT SUPER ON *.* TO sha256_user@'%'/, + q/GRANT SELECT ON mysql.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/Grants dumped by/, + 'It lives', +); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', $cnf, + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/Grants dumped by/, + 'It lives with option --mysql_ssl', +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', 't/pt-archiver/samples/pt-191.cnf', + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_show_grants::main( + '-F', 't/pt-archiver/samples/pt-191-error.cnf', + 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', + qw(--drop --flush --revoke --separate) + ); }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-table-checksum/ssl.t b/t/pt-table-checksum/ssl.t index 76e46fd25..121e6e369 100644 --- a/t/pt-table-checksum/ssl.t +++ b/t/pt-table-checksum/ssl.t @@ -19,22 +19,31 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic +# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die. +# And --max-load "" prevents waiting for status variables. +my @args = (qw(--set-vars innodb_lock_wait_timeout=3), '--max-load', ''); +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', qw(-d test)) }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } else { - plan tests => 15; + plan tests => 23; } -# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic -# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die. -# And --max-load "" prevents waiting for status variables. -my @args = (qw(--set-vars innodb_lock_wait_timeout=3), '--max-load', ''); -my ($output, $exit_code); - # ############################################################################# # Issue 388: mk-table-checksum crashes when column with comma in the name # is used in a key @@ -175,6 +184,72 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', qw(-d test)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +unlike( + $output, + qr/Use of uninitialized value/, + 'No error (issue 388) with option --mysql_ssl_optional (short version -o)' +); + +like( + $output, + qr/^\S+\s+0\s+0\s+1\s+0\s+1\s+/m, + 'Checksums the table (issue 388) with option --mysql_ssl_optional (short version -o)' +); + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main( + @args, + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + qw(-d test)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +unlike( + $output, + qr/Use of uninitialized value/, + 'No error (issue 388) with option --mysql_ssl and --mysql_ssl_optional' +); + +like( + $output, + qr/^\S+\s+0\s+0\s+1\s+0\s+1\s+/m, + 'Checksums the table (issue 388) with option --mysql_ssl and --mysql_ssl_optional' +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-table-checksum/ssl_optional.t b/t/pt-table-checksum/ssl_optional.t new file mode 100644 index 000000000..de80a89d6 --- /dev/null +++ b/t/pt-table-checksum/ssl_optional.t @@ -0,0 +1,194 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-table-checksum"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic +# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die. +# And --max-load "" prevents waiting for status variables. +my @args = (qw(--set-vars innodb_lock_wait_timeout=3), '--max-load', ''); +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1', qw(-d test)) }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} +else { + plan tests => 15; +} + +# ############################################################################# +# Issue 388: mk-table-checksum crashes when column with comma in the name +# is used in a key +# ############################################################################# + +$sb->create_dbs($dbh, [qw(test)]); +$sb->load_file('source', 't/lib/samples/tables/issue-388.sql', 'test'); + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON test.* TO sha256_user@'%'/, + q/GRANT SELECT ON test_ssl.* TO sha256_user@'%'/, + q/GRANT ALL ON percona.* TO sha256_user@'%'/, + q/GRANT REPLICATION SLAVE ON *.* TO sha256_user@'%'/, + q/GRANT REPLICATION CLIENT ON *.* TO sha256_user@'%'/, +); + +$sb->load_file('source', "t/pt-online-schema-change/samples/ssl_dsns.sql"); +$dbh->do("insert into test.foo values (null, 'john, smith')"); + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=0', qw(-d test)) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', qw(-d test)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +unlike( + $output, + qr/Use of uninitialized value/, + 'No error (issue 388)' +); + +like( + $output, + qr/^\S+\s+0\s+0\s+1\s+0\s+1\s+/m, + 'Checksums the table (issue 388)' +); + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main( + @args, + qw(--host 127.1 --port 12345 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + qw(-d test)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +unlike( + $output, + qr/Use of uninitialized value/, + 'No error (issue 388) with option --mysql_ssl' +); + +like( + $output, + qr/^\S+\s+0\s+0\s+1\s+0\s+1\s+/m, + 'Checksums the table (issue 388) with option --mysql_ssl' +); + +($output, $exit_code) = full_output( + sub { + pt_table_checksum::main( + @args, + 'F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', + qw(-d test), + "--recursion-method=dsn=F=t/pt-archiver/samples/pt-191.cnf,D=test_ssl,t=dsns,h=127.0.0.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_table_checksum::main(@args, 'F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1', qw(-d test)) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/t/pt-table-sync/ssl.t b/t/pt-table-sync/ssl.t index fa1a4aaba..243c2f61c 100644 --- a/t/pt-table-sync/ssl.t +++ b/t/pt-table-sync/ssl.t @@ -20,7 +20,19 @@ my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $source_dbh = $sb->get_dbh_for('source'); my $replica_dbh = $sb->get_dbh_for('replica1'); -if ( !$source_dbh ) { +my ($output, $exit_code); +my @args = (qw(--sync-to-source -t sakila.actor -v -v --print --chunk-size 100)); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_sync::main('h=127.1,P=12346,D=sakila,t=film,u=msandbox,p=msandbox,s=1', @args) }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( !$replica_dbh ) { @@ -30,12 +42,9 @@ elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } else { - plan tests => 13; + plan tests => 19; } -my ($output, $exit_code); -my @args = (qw(--sync-to-source -t sakila.actor -v -v --print --chunk-size 100)); - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -161,6 +170,60 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +@args = (qw(--sync-to-source -t sakila.actor -v -v --print --chunk-size 100)); + +($output, $exit_code) = full_output( + sub { pt_table_sync::main('h=127.1,P=12346,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1', @args) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +like( + $output, + qr/WHERE \(`film_id` = 0\)/, + "Zero chunk with option --mysql_ssl_optional (short version -o)" +); + +($output, $exit_code) = full_output( + sub { pt_table_sync::main('D=sakila,t=film', + qw(--host 127.1 --port 12346 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), @args) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +like( + $output, + qr/WHERE \(`film_id` = 0\)/, + "Zero chunk with option --mysql_ssl and --mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-table-sync/ssl_optional.t b/t/pt-table-sync/ssl_optional.t new file mode 100644 index 000000000..b49dcf53c --- /dev/null +++ b/t/pt-table-sync/ssl_optional.t @@ -0,0 +1,180 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-table-sync"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $source_dbh = $sb->get_dbh_for('source'); +my $replica_dbh = $sb->get_dbh_for('replica1'); + +my ($output, $exit_code); +my @args = (qw(--sync-to-source -t sakila.actor -v -v --print --chunk-size 100)); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_sync::main('h=127.1,P=12346,D=sakila,t=film,u=msandbox,p=msandbox,s=1', @args) }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$source_dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( !$replica_dbh ) { + plan skip_all => 'Cannot connect to sandbox replica'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} +else { + plan tests => 13; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, + q/GRANT ALL ON percona.* TO sha256_user@'%'/, + q/GRANT SELECT ON test_ssl.* TO sha256_user@'%'/, + q/GRANT REPLICATION CLIENT ON *.* TO sha256_user@'%'/, + q/GRANT PROCESS ON *.* TO sha256_user@'%'/, +); + +$sb->load_file('source', "t/pt-online-schema-change/samples/ssl_dsns.sql"); + +($output, $exit_code) = full_output( + sub { pt_table_sync::main('h=127.1,P=12346,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=0', @args) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_table_sync::main('h=127.1,P=12346,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1', @args) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +like( + $output, + qr/WHERE \(`film_id` = 0\)/, + "Zero chunk" +); + +($output, $exit_code) = full_output( + sub { pt_table_sync::main('D=sakila,t=film', + qw(--host 127.1 --port 12346 --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), @args) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +like( + $output, + qr/WHERE \(`film_id` = 0\)/, + "Zero chunk with option --mysql_ssl" +); + +# Prepare checksums table +diag(`$trunk/bin/pt-table-checksum F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 -d sakila --recursion-method=dsn=F=t/pt-archiver/samples/pt-191.cnf,D=test_ssl,t=dsns,h=127.0.0.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1 2>&1 >/dev/null`); + +@args = (qw(--recursion-method=dsn --replicate=percona.checksums -t sakila.actor -v -v --print --chunk-size 100)); +($output, $exit_code) = full_output( + sub { + pt_table_sync::main( + 'F=t/pt-archiver/samples/pt-191,h=127.1,P=12346,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1', + @args, + "--recursion-method=dsn=F=t/pt-archiver/samples/pt-191-replica1.cnf,D=test_ssl,t=dsns,h=127.0.0.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1" + ) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_table_sync::main( + 'F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,D=sakila,t=film,u=sha256_user,p=sha256_user%password,s=1,o=1', + @args, + "--recursion-method=dsn=F=t/pt-archiver/samples/pt-191.cnf,D=test_ssl,t=dsns,h=127.0.0.1,P=12345,u=sha256_user,p=sha256_user%password,s=1,o=1" + ) }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($source_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/t/pt-table-usage/ssl.t b/t/pt-table-usage/ssl.t index 387296ff5..7932c9f8d 100644 --- a/t/pt-table-usage/ssl.t +++ b/t/pt-table-usage/ssl.t @@ -19,19 +19,29 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_usage::main("--explain-extended=F=$cnf,h=127.1,P=12345,D=sakila,u=msandbox,p=msandbox,s=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } else { - plan tests => 13; + plan tests => 19; } -my ($output, $exit_code); -my $cnf = '/tmp/12345/my.sandbox.cnf'; - my $in = "$trunk/t/pt-table-usage/samples/in"; my $out = "t/pt-table-usage/samples/out"; @@ -145,6 +155,60 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', "F=$cnf,h=127.1,P=12345,D=sakila,u=sha256_user,p=sha256_user%password,s=1,o=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +is( + $output, + "", + "No error if table doesn't exist with option --mysql_ssl_optional (short version -o)" +); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', + qw(127.1 --port 12345 --database sakila --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +is( + $output, + "", + "No error if table doesn't exist with option --mysql_ssl and --mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-table-usage/ssl_optional.t b/t/pt-table-usage/ssl_optional.t new file mode 100644 index 000000000..94451529e --- /dev/null +++ b/t/pt-table-usage/ssl_optional.t @@ -0,0 +1,164 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-table-usage"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_table_usage::main("--explain-extended=F=$cnf,h=127.1,P=12345,D=sakila,u=msandbox,p=msandbox,s=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} +else { + plan tests => 13; +} + +my $in = "$trunk/t/pt-table-usage/samples/in"; +my $out = "t/pt-table-usage/samples/out"; + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main("--explain-extended=F=$cnf,h=127.1,P=12345,D=sakila,u=sha256_user,p=sha256_user%password,s=0", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', "F=$cnf,h=127.1,P=12345,D=sakila,u=sha256_user,p=sha256_user%password,s=1,o=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +is( + $output, + "", + "No error if table doesn't exist" +); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', + qw(127.1 --port 12345 --database sakila --user sha256_user), + qw(--password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +is( + $output, + "", + "No error if table doesn't exist with option --mysql_ssl" +); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', "F=t/pt-archiver/samples/pt-191.cnf,h=127.1,P=12345,D=sakila,u=sha256_user,p=sha256_user%password,s=1,o=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_table_usage::main('--explain-extended', "F=t/pt-archiver/samples/pt-191-error.cnf,h=127.1,P=12345,D=sakila,u=sha256_user,p=sha256_user%password,s=1,o=1", + '--query', 'select * from foo, bar where id=1') }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/t/pt-upgrade/ssl.t b/t/pt-upgrade/ssl.t index 95499ad58..96b62c6e2 100644 --- a/t/pt-upgrade/ssl.t +++ b/t/pt-upgrade/ssl.t @@ -24,20 +24,32 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh1 = $sb->get_dbh_for('host1'); +my $host1_dsn = $sb->dsn_for('host1'); +my $tmpdir = tempdir("/tmp/pt-upgrade.$PID.XXXXXX", CLEANUP => 1); +my $samples = "$trunk/t/pt-upgrade/samples"; +my $lib_samples = "$trunk/t/lib/samples"; +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn},u=msandbox,p=msandbox,s=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); -if ( !$dbh1 ) { +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh1 ) { plan skip_all => 'Cannot connect to sandbox host1'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my $host1_dsn = $sb->dsn_for('host1'); -my $tmpdir = tempdir("/tmp/pt-upgrade.$PID.XXXXXX", CLEANUP => 1); -my $samples = "$trunk/t/pt-upgrade/samples"; -my $lib_samples = "$trunk/t/lib/samples"; -my ($output, $exit_code); - # ############################################################################# # genlog # ############################################################################# @@ -169,6 +181,66 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn},u=sha256_user,p=sha256_user%password,s=1,o=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +is( + $exit_code, + 0, + "Does not fail on SELECT...INTO statements with option --mysql_ssl_optional (short version -o)" +); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn}", + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1), + '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +is( + $exit_code, + 0, + "Does not fail on SELECT...INTO statements with option --mysql_ssl and --mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-upgrade/ssl_optional.t b/t/pt-upgrade/ssl_optional.t new file mode 100644 index 000000000..fcbf92ea3 --- /dev/null +++ b/t/pt-upgrade/ssl_optional.t @@ -0,0 +1,191 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; +use File::Basename; +use File::Temp qw(tempdir); + +$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1; +$ENV{PRETTY_RESULTS} = 1; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-upgrade"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh1 = $sb->get_dbh_for('host1'); + +my $host1_dsn = $sb->dsn_for('host1'); +my $tmpdir = tempdir("/tmp/pt-upgrade.$PID.XXXXXX", CLEANUP => 1); +my $samples = "$trunk/t/pt-upgrade/samples"; +my $lib_samples = "$trunk/t/lib/samples"; +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn},u=msandbox,p=msandbox,s=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh1 ) { + plan skip_all => 'Cannot connect to sandbox host1'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +# ############################################################################# +# genlog +# ############################################################################# + +`rm -f /tmp/test_select_into_*.log`; + +$sb->do_as_root( + 'host1', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON *.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn},u=sha256_user,p=sha256_user%password,s=0", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn},u=sha256_user,p=sha256_user%password,s=1,o=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +is( + $exit_code, + 0, + "Does not fail on SELECT...INTO statements" +); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("${host1_dsn}", + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1), + '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log", + )}, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +is( + $exit_code, + 0, + "Does not fail on SELECT...INTO statements with option --mysql_ssl" +); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("F=t/pt-archiver/samples/pt-191.cnf,${host1_dsn},u=sha256_user,p=sha256_user%password,s=1,o=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log") + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_upgrade::main("F=t/pt-archiver/samples/pt-191-error.cnf,${host1_dsn},u=sha256_user,p=sha256_user%password,s=1,o=1", '--save-results', $tmpdir, + qw(--type rawlog), + "$samples/select_into.log") + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('host1', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh1); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-variable-advisor/ssl.t b/t/pt-variable-advisor/ssl.t index e0a6d8f1c..30d23cb0a 100644 --- a/t/pt-variable-advisor/ssl.t +++ b/t/pt-variable-advisor/ssl.t @@ -20,7 +20,18 @@ my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); my $dsn = $sb->dsn_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn},u=msandbox,p=msandbox,s=1") }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => "Cannot connect to sandbox source"; } elsif ( $sandbox_version lt '8.0' ) { @@ -39,8 +50,6 @@ $sb->do_as_root( q/GRANT ALL ON sakila.* TO sha256_user@'%'/, ); -my ($output, $exit_code); - ($output, $exit_code) = full_output( sub { pt_variable_advisor::main("${dsn},u=sha256_user,p=sha256_user%password,s=0") }, stderr => 1, @@ -139,6 +148,57 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn},u=sha256_user,p=sha256_user%password,s=1,o=1") }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional (short version -o)" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional (short version -o)' +) or diag($output); + +unlike( + $output, + qr/innodb_max_dirty_pages_pct/, + "No innodb_max_dirty_pages_pct warning (bug 1168106) with option --mysql_ssl_optional (short version -o)" +); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn}", + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional 1)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl and --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl and --mysql_ssl_optional' +) or diag($output); + +unlike( + $output, + qr/innodb_max_dirty_pages_pct/, + "No innodb_max_dirty_pages_pct warning (bug 1168106) with option --mysql_ssl and --mysql_ssl_optional" +); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-variable-advisor/ssl_optional.t b/t/pt-variable-advisor/ssl_optional.t new file mode 100644 index 000000000..2ea302a58 --- /dev/null +++ b/t/pt-variable-advisor/ssl_optional.t @@ -0,0 +1,157 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-variable-advisor"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); +my $dsn = $sb->dsn_for('source'); + +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn},u=msandbox,p=msandbox,s=1") }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => "Cannot connect to sandbox source"; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +# ############################################################################# +# https://bugs.launchpad.net/percona-toolkit/+bug/1168106 +# pt-variable-advisor has the wrong default value for +# innodb_max_dirty_pages_pct in 5.6.10 +# ############################################################################# + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn},u=sha256_user,p=sha256_user%password,s=0") }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn},u=sha256_user,p=sha256_user%password,s=1,o=1") }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +unlike( + $output, + qr/innodb_max_dirty_pages_pct/, + "No innodb_max_dirty_pages_pct warning (bug 1168106)" +); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("${dsn}", + qw(--user sha256_user --password sha256_user%password --mysql_ssl 1 --mysql_ssl_optional=1)) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with option --mysql_ssl' +) or diag($output); + +unlike( + $output, + qr/innodb_max_dirty_pages_pct/, + "No innodb_max_dirty_pages_pct warning (bug 1168106) with option --mysql_ssl" +); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("F=t/pt-archiver/samples/pt-191.cnf,${dsn},u=sha256_user,p=sha256_user%password,s=1,o=1") }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { pt_variable_advisor::main("F=t/pt-archiver/samples/pt-191-error.cnf,${dsn},u=sha256_user,p=sha256_user%password,s=1,o=1") }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-visual-explain/ssl.t b/t/pt-visual-explain/ssl.t index a75e060f0..5a4196591 100644 --- a/t/pt-visual-explain/ssl.t +++ b/t/pt-visual-explain/ssl.t @@ -19,15 +19,30 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $dbh = $sb->get_dbh_for('source'); -if ( !$dbh ) { +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(--host=127.1 --port=12345 --user=msandbox --password=msandbox --mysql_ssl=1) + ) + }, + stderr => 1, +); + +if ( $exit_code != 0 || $output =~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test does not work with DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox source'; } elsif ( $sandbox_version lt '8.0' ) { plan skip_all => "Requires MySQL 8.0 or newer"; } -my ($output, $exit_code); - $sb->do_as_root( 'source', q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, @@ -126,6 +141,33 @@ like( 'SSL connection error with incorrect SSL options in the configuration file' ) or diag($output); +# ############################################################################# +# Test mysql_ssl_optional option +# ############################################################################# + +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1) + ) + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password with option --mysql_ssl_optional" +) or diag($output); + +unlike( + $output, + qr/Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection./, + 'No secure connection error with option --mysql_ssl_optional' +) or diag($output); + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-visual-explain/ssl_optional.t b/t/pt-visual-explain/ssl_optional.t new file mode 100644 index 000000000..19efbc87e --- /dev/null +++ b/t/pt-visual-explain/ssl_optional.t @@ -0,0 +1,151 @@ +#!/usr/bin/env perl + +BEGIN { + die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" + unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; + unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; +}; + +use strict; +use warnings FATAL => 'all'; +use English qw(-no_match_vars); +use Test::More; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-visual-explain"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +my ($output, $exit_code); + +# Testing if we are using DBD::mysql compiled with MariaDB library, which does not support enforcing SSL encryption +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(--host=127.1 --port=12345 --user=msandbox --password=msandbox --mysql_ssl=1) + ) + }, + stderr => 1, +); + +if ( $exit_code == 0 || $output !~ /SSL connection error: Enforcing SSL encryption is not supported/ ) { + plan skip_all => "Test requires DBD::mysql compiled with MariaDB library that does not support enforcing SSL encryption"; +} +elsif ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->do_as_root( + 'source', + q/CREATE USER IF NOT EXISTS sha256_user@'%' IDENTIFIED WITH caching_sha2_password BY 'sha256_user%password' REQUIRE SSL/, + q/GRANT ALL ON sakila.* TO sha256_user@'%'/, +); + +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=0) + ) + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error raised when SSL connection is not used" +) or diag($output); + +like( + $output, + qr/Access denied/, + 'Secure connection error raised when no SSL connection used' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(--host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1) + ) + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for user, identified with caching_sha2_password" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(-F t/pt-archiver/samples/pt-191.cnf --host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1) + ) + }, + stderr => 1, +); + +is( + $exit_code, + 0, + "No error for SSL options in the configuration file" +) or diag($output); + +unlike( + $output, + qr/Access denied/, + 'No secure connection error with correct SSL options in the configuration file' +) or diag($output); + +($output, $exit_code) = full_output( + sub { + pt_visual_explain::main( + '--connect', + 't/pt-visual-explain/samples/query.sql', + qw(-F t/pt-archiver/samples/pt-191-error.cnf --host=127.1 --port=12345 --user=sha256_user --password=sha256_user%password --mysql_ssl=1 --mysql_ssl_optional=1) + ) + }, + stderr => 1, +); + +isnt( + $exit_code, + 0, + "Error for invalid SSL options in the configuration file" +) or diag($output); + +like( + $output, + qr/SSL error: key values mismatch/, + 'SSL connection error with incorrect SSL options in the configuration file' +) or diag($output); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', q/DROP USER 'sha256_user'@'%'/); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing;