248 lines
9.1 KiB
C++
248 lines
9.1 KiB
C++
/**
|
|
* @file mxs1073_binlog_enc.cpp Test binlog router setup with binlogs encryption
|
|
* - configure binlog router with follwoing options
|
|
@verbatim
|
|
encrypt_binlog=1,encryption_key_file=/etc/mariadb_binlog_keys.txt,encryption_algorithm=aes_cbc
|
|
@endverbatim
|
|
* - put some date to Master
|
|
* - check that all slave have the same data
|
|
* - 'maxbinlogcheck' against Maxscale binlog file
|
|
* - check 'maxbinlogcheck' output for lack of errors and presence of 'Decrypting binlog file with algorithm' message
|
|
* - try remote access to Maxscale binlog with 'mysqlbinlog'
|
|
* - copy Maxscale binlogs to Master and check output of 'show binary logs' before and after copying
|
|
* (expect same file name and size, but different checksums)
|
|
*/
|
|
|
|
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include "testconnections.h"
|
|
#include "test_binlog_fnc.h"
|
|
|
|
/**
|
|
* @brief get_first_binlog_file Get name, size and checksum of first binlog file from 'show binary logs' output list
|
|
* @param Test TestConnections object
|
|
* @param name string for file name
|
|
* @param size variable for file size
|
|
* @param checksum Pointer to checksum string
|
|
* @return 0 in case of success
|
|
*/
|
|
int get_first_binlog_file(TestConnections * Test, char * name, long long unsigned *size, char ** checksum)
|
|
{
|
|
char size_str[64];
|
|
char cmd[256];
|
|
int res = 0;
|
|
int exit_code;
|
|
res = find_field(Test->repl->nodes[0], (char *) "SHOW BINARY LOGS", (char *) "Log_name", name);
|
|
res += find_field(Test->repl->nodes[0], (char *) "SHOW BINARY LOGS", (char *) "File_size", size_str);
|
|
|
|
sscanf(size_str, "%llu", size);
|
|
sprintf(cmd, "sha1sum /var/lib/mysql/%s | cut -f 1 -d \" \"", name);
|
|
|
|
*checksum = Test->repl->ssh_node_output(0, cmd, true, &exit_code);
|
|
if (exit_code != 0)
|
|
{
|
|
res++;
|
|
}
|
|
|
|
Test->tprintf("First master binlog file:\nname: '%s'\nsize: %llu\nchecksum: %s\n",
|
|
name,
|
|
*size,
|
|
*checksum
|
|
);
|
|
|
|
return res;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
|
|
printf("ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!\n"
|
|
"ERROR! ERROR!\n"
|
|
"ERROR! This test require file key management plugin! ERROR!\n"
|
|
"ERROR! ERROR!\n"
|
|
"ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!ERROR!\n");
|
|
return 1;
|
|
|
|
|
|
TestConnections * Test = new TestConnections(argc, argv);
|
|
Test->set_timeout(1000);
|
|
char str1[1024];
|
|
char str2[1024];
|
|
char * alg;
|
|
char * alg1 = (char *) "aes_cbc";
|
|
char * alg2 = (char *) "aes_ctr";
|
|
|
|
Test->tprintf("%s %s\n", Test->test_name, argv[1]);
|
|
|
|
if (strcmp(Test->test_name, "mxs1073_binlog_enc_aes_ctr") == 0)
|
|
{
|
|
alg = alg2;
|
|
}
|
|
else
|
|
{
|
|
alg = alg1;
|
|
}
|
|
|
|
int i;
|
|
|
|
Test->repl->connect();
|
|
Test->try_query(Test->repl->nodes[0], (char *) "DROP TABLE IF EXISTS t1");
|
|
|
|
|
|
Test->tprintf("Coping encription config .cnf files to all nodes \n");
|
|
sprintf(str1, "%s/binlog_enc_%s.cnf", Test->test_dir, alg);
|
|
sprintf(str2, "%s/mariadb_binlog_keys.txt", Test->test_dir);
|
|
for (i = 0; i < Test->repl->N; i++)
|
|
{
|
|
Test->repl->copy_to_node(str1, (char *) "~/", i);
|
|
Test->repl->ssh_node(i, (char *) "cp ~/binlog_enc*.cnf /etc/my.cnf.d/", true);
|
|
|
|
Test->repl->copy_to_node(str2, (char *) "~/", i);
|
|
Test->repl->ssh_node(i, (char *) "cp ~/mariadb_binlog_keys.txt /etc/", true);
|
|
}
|
|
|
|
Test->copy_to_maxscale(str2, (char *) "~/");
|
|
Test->ssh_maxscale(true, "cp ~/mariadb_binlog_keys.txt /etc/");
|
|
|
|
Test->start_binlog();
|
|
|
|
Test->repl->connect();
|
|
|
|
Test->tprintf("Put some data to DB\n");
|
|
Test->set_timeout(100);
|
|
create_t1(Test->repl->nodes[0]);
|
|
Test->add_result(insert_into_t1(Test->repl->nodes[0], 4), "Data inserting to t1 failed\n");
|
|
Test->stop_timeout();
|
|
Test->tprintf("Sleeping to let replication happen\n");
|
|
sleep(60);
|
|
|
|
for (i = 0; i < Test->repl->N; i++)
|
|
{
|
|
Test->tprintf("Checking data from node %d (%s)\n", i, Test->repl->IP[i]);
|
|
Test->set_timeout(100);
|
|
Test->add_result(select_from_t1(Test->repl->nodes[i], 4), "Selecting from t1 failed\n");
|
|
Test->stop_timeout();
|
|
}
|
|
|
|
Test->tprintf("Flush logs\n");
|
|
execute_query(Test->repl->nodes[0], (char *) "FLUSH LOGS");
|
|
|
|
Test->tprintf("Running 'maxbinlogcheck' against Maxscale binlog file\n");
|
|
char * maxscale_binlogcheck_output = Test->ssh_maxscale_output(true,
|
|
"maxbinlogcheck -M -K /etc/mariadb_binlog_keys.txt -H /var/lib/maxscale/Binlog_Service/mar-bin.000001 --aes_algo=%s 2> 1",
|
|
alg);
|
|
//puts(maxscale_binlogcheck_output);
|
|
if (strstr(maxscale_binlogcheck_output, "error") != NULL)
|
|
{
|
|
Test->add_result(1, "Errors in the maxbinlogcheck output:\n%s\n", maxscale_binlogcheck_output);
|
|
}
|
|
|
|
sprintf(str1, "Decrypting binlog file with algorithm: %s", alg);
|
|
if (strstr(maxscale_binlogcheck_output, str1) == NULL)
|
|
{
|
|
Test->add_result(1, "No '%s' in the maxbinlogcheck output:\n%s\n", str1, maxscale_binlogcheck_output);
|
|
}
|
|
|
|
sprintf(str1,
|
|
"mysqlbinlog -R -h %s -P %d -u%s -p%s mar-bin.000001 --stop-position=60000",
|
|
Test->maxscale_IP, Test->binlog_port, Test->maxscale_user, Test->maxscale_password);
|
|
Test->tprintf("running mysqlbinlog on node_000 to connecto Maxscale: %s\n", str1);
|
|
int exit_code;
|
|
char * mysql_binlog_connect_output = Test->repl->ssh_node_output(0, str1, false, &exit_code);
|
|
Test->add_result(exit_code, "Remote access to Maxscale binlog failed");
|
|
sprintf(str1, "LOGS/%s/mysql_binlog_connect_output", Test->test_name);
|
|
FILE *f = fopen(str1, "wt");
|
|
fprintf(f, "%s", mysql_binlog_connect_output);
|
|
fclose(f);
|
|
|
|
Test->tprintf("Checking binlog files on master\n");
|
|
long long unsigned size_before;
|
|
long long unsigned size_after;
|
|
long long unsigned size_after_restart;
|
|
char * checksum_before;
|
|
char * checksum_after;
|
|
char * checksum_after_restart;
|
|
char name_before[256];
|
|
char name_after[256];
|
|
char name_after_restart[256];
|
|
|
|
Test->add_result(get_first_binlog_file(Test, name_before, &size_before, &checksum_before),
|
|
"Error getting binlog name and size\n");
|
|
|
|
Test->tprintf("Copying binlogs from Maxscale to Master\n");
|
|
system("rm -rf binlogs");
|
|
system("mkdir binlogs");
|
|
Test->copy_from_maxscale((char *) "/var/lib/maxscale/Binlog_Service/*", (char *) "binlogs/");
|
|
Test->repl->ssh_node(0, "rm -rf binlogs", true);
|
|
Test->repl->copy_to_node("-r binlogs", "./", 0);
|
|
Test->repl->ssh_node(0, "chown mysql:mysql binlogs/*", true);
|
|
|
|
|
|
//Test->repl->ssh_node(0, "rm /var/lib/mysql/mar-bin*", true);
|
|
Test->repl->ssh_node(0, "cp binlogs/* /var/lib/mysql/", true);
|
|
sleep(5);
|
|
Test->tprintf("Checking binlog files on master after copying binlogs from Maxscale\n");
|
|
Test->add_result(get_first_binlog_file(Test, name_after, &size_after, &checksum_after),
|
|
"Error getting binlog name and size\n");
|
|
|
|
Test->repl->close_connections();
|
|
|
|
if (size_before != size_after)
|
|
{
|
|
Test->add_result(1, "Master binlog file size after copying Maxscale binlogs to Master is different\n");
|
|
}
|
|
if (strcmp(name_before, name_after) != 0)
|
|
{
|
|
Test->add_result(1, "Master binlog file name after copying Maxscale binlogs to Master is different\n");
|
|
}
|
|
if (strcmp(checksum_before, checksum_after) == 0)
|
|
{
|
|
Test->add_result(1,
|
|
"Master binlog file checksum after copying Maxscale binlogs to Master is the same. Probably binlog copying error different\n");
|
|
}
|
|
|
|
Test->repl->stop_node(0);
|
|
Test->repl->start_node(0, (char *) "");
|
|
sleep(5);
|
|
|
|
Test->tprintf("Checking binlog files on master after copying binlogs from Maxscale and Master restart\n");
|
|
Test->repl->connect();
|
|
Test->add_result(get_first_binlog_file(Test, name_after_restart, &size_after_restart,
|
|
&checksum_after_restart),
|
|
"Error getting binlog name and size\n");
|
|
Test->repl->close_connections();
|
|
|
|
if (size_before != size_after_restart)
|
|
{
|
|
Test->add_result(1,
|
|
"Master binlog file size after copying Maxscale binlogs to Master and restart is different\n");
|
|
}
|
|
if (strcmp(name_before, name_after_restart) != 0)
|
|
{
|
|
Test->add_result(1,
|
|
"Master binlog file name after copying Maxscale binlogs to Master and restart is different\n");
|
|
}
|
|
if (strcmp(checksum_after_restart, checksum_after) != 0)
|
|
{
|
|
Test->add_result(1, "Master binlog file checksum after Master restart is different\n");
|
|
}
|
|
|
|
|
|
// clean up
|
|
Test->tprintf("Cleaning up nodes and restart replication\n");
|
|
Test->repl->stop_nodes();
|
|
for (i = 0; i < Test->repl->N; i++)
|
|
{
|
|
Test->repl->ssh_node(i, (char *) "rm /etc/my.cnf.d/binlog_enc*.cnf", true);
|
|
Test->repl->ssh_node(i, (char *) "rm /etc/mariadb_binlog_keys.txt", true);
|
|
}
|
|
Test->repl->start_replication();
|
|
|
|
|
|
|
|
int rval = Test->global_result;
|
|
delete Test;
|
|
return rval;
|
|
}
|