Skip to content

Commit

Permalink
Merge pull request sysown#4458 from sysown/v2.x_Servers_SSL_Params
Browse files Browse the repository at this point in the history
Introducing mysql_servers_ssl_params
  • Loading branch information
renecannao authored Feb 28, 2024
2 parents ee4cd19 + 548eded commit 8a4246d
Show file tree
Hide file tree
Showing 8 changed files with 423 additions and 22 deletions.
74 changes: 74 additions & 0 deletions include/MySQL_HostGroups_Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ using json = nlohmann::json;

#define MYHGM_MYSQL_HOSTGROUP_ATTRIBUTES "CREATE TABLE mysql_hostgroup_attributes (hostgroup_id INT NOT NULL PRIMARY KEY , max_num_online_servers INT CHECK (max_num_online_servers>=0 AND max_num_online_servers <= 1000000) NOT NULL DEFAULT 1000000 , autocommit INT CHECK (autocommit IN (-1, 0, 1)) NOT NULL DEFAULT -1 , free_connections_pct INT CHECK (free_connections_pct >= 0 AND free_connections_pct <= 100) NOT NULL DEFAULT 10 , init_connect VARCHAR NOT NULL DEFAULT '' , multiplex INT CHECK (multiplex IN (0, 1)) NOT NULL DEFAULT 1 , connection_warming INT CHECK (connection_warming IN (0, 1)) NOT NULL DEFAULT 0 , throttle_connections_per_sec INT CHECK (throttle_connections_per_sec >= 1 AND throttle_connections_per_sec <= 1000000) NOT NULL DEFAULT 1000000 , ignore_session_variables VARCHAR CHECK (JSON_VALID(ignore_session_variables) OR ignore_session_variables = '') NOT NULL DEFAULT '' , hostgroup_settings VARCHAR CHECK (JSON_VALID(hostgroup_settings) OR hostgroup_settings = '') NOT NULL DEFAULT '' , servers_defaults VARCHAR CHECK (JSON_VALID(servers_defaults) OR servers_defaults = '') NOT NULL DEFAULT '' , comment VARCHAR NOT NULL DEFAULT '')"


#define MYHGM_MYSQL_SERVERS_SSL_PARAMS "CREATE TABLE mysql_servers_ssl_params (hostname VARCHAR NOT NULL , port INT CHECK (port >= 0 AND port <= 65535) NOT NULL DEFAULT 3306 , username VARCHAR NOT NULL DEFAULT '' , ssl_ca VARCHAR NOT NULL DEFAULT '' , ssl_cert VARCHAR NOT NULL DEFAULT '' , ssl_key VARCHAR NOT NULL DEFAULT '' , ssl_capath VARCHAR NOT NULL DEFAULT '' , ssl_crl VARCHAR NOT NULL DEFAULT '' , ssl_crlpath VARCHAR NOT NULL DEFAULT '' , ssl_cipher VARCHAR NOT NULL DEFAULT '' , tls_version VARCHAR NOT NULL DEFAULT '' , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostname, port, username) )"

/*
* @brief Generates the 'runtime_mysql_servers' resultset exposed to other ProxySQL cluster members.
* @details Makes 'SHUNNED' and 'SHUNNED_REPLICATION_LAG' statuses equivalent to 'ONLINE'. 'SHUNNED' states
Expand Down Expand Up @@ -377,6 +380,68 @@ class AWS_Aurora_Info {
~AWS_Aurora_Info();
};

class MySQLServers_SslParams {
public:
string hostname;
int port;
string username;
string ssl_ca;
string ssl_cert;
string ssl_key;
string ssl_capath;
string ssl_crl;
string ssl_crlpath;
string ssl_cipher;
string tls_version;
string comment;
string MapKey;
MySQLServers_SslParams(string _h, int _p, string _u,
string ca, string cert, string key, string capath,
string crl, string crlpath, string cipher, string tls,
string c) {
hostname = _h;
port = _p;
username = _u;
ssl_ca = ca;
ssl_cert = cert;
ssl_key = key;
ssl_capath = capath;
ssl_crl = crl;
ssl_crlpath = crlpath;
ssl_cipher = cipher;
tls_version = tls;
comment = c;
MapKey = "";
}
MySQLServers_SslParams(char * _h, int _p, char * _u,
char * ca, char * cert, char * key, char * capath,
char * crl, char * crlpath, char * cipher, char * tls,
char * c) {
hostname = string(_h);
port = _p;
username = string(_u);
ssl_ca = string(ca);
ssl_cert = string(cert);
ssl_key = string(key);
ssl_capath = string(capath);
ssl_crl = string(crl);
ssl_crlpath = string(crlpath);
ssl_cipher = string(cipher);
tls_version = string(tls);
comment = string(c);
MapKey = "";
}
MySQLServers_SslParams(string _h, int _p, string _u) {
MySQLServers_SslParams(_h, _p, _u, "", "", "", "", "", "", "", "", "");
}
string getMapKey(const char *del) {
if (MapKey == "") {
MapKey = hostname + string(del) + to_string(port) + string(del) + username;
}
return MapKey;
}
};

struct p_hg_counter {
enum metric {
servers_table_version = 0,
Expand Down Expand Up @@ -528,6 +593,7 @@ class MySQL_HostGroups_Manager {
MYSQL_GALERA_HOSTGROUPS,
MYSQL_AWS_AURORA_HOSTGROUPS,
MYSQL_HOSTGROUP_ATTRIBUTES,
MYSQL_SERVERS_SSL_PARAMS,
MYSQL_SERVERS,

__HGM_TABLES_SIZE
Expand Down Expand Up @@ -637,6 +703,9 @@ class MySQL_HostGroups_Manager {
PtrArray *MyHostGroups;
std::unordered_map<unsigned int, MyHGC *>MyHostGroups_map;

std::mutex Servers_SSL_Params_map_mutex;
std::unordered_map<std::string, MySQLServers_SslParams> Servers_SSL_Params_map;

MyHGC * MyHGC_find(unsigned int);
MyHGC * MyHGC_create(unsigned int);

Expand Down Expand Up @@ -711,6 +780,9 @@ class MySQL_HostGroups_Manager {
void generate_mysql_hostgroup_attributes_table();
SQLite3_result *incoming_hostgroup_attributes;

void generate_mysql_servers_ssl_params_table();
SQLite3_result *incoming_mysql_servers_ssl_params;

SQLite3_result* incoming_mysql_servers_v2;

std::thread *HGCU_thread;
Expand Down Expand Up @@ -1116,6 +1188,8 @@ class MySQL_HostGroups_Manager {
void unshun_server_all_hostgroups(const char * address, uint16_t port, time_t t, int max_wait_sec, unsigned int *skip_hid);
MySrvC* find_server_in_hg(unsigned int _hid, const std::string& addr, int port);

MySQLServers_SslParams * get_Server_SSL_Params(char *hostname, int port, char *username);

private:
void update_hostgroup_manager_mappings();
uint64_t get_mysql_servers_checksum(SQLite3_result* runtime_mysql_servers = nullptr);
Expand Down
5 changes: 5 additions & 0 deletions include/ProxySQL_Cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_hostgroup_attributes'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_HOSTGROUP_ATTRIBUTES "PROXY_SELECT hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, hostgroup_settings, servers_defaults, comment FROM runtime_mysql_hostgroup_attributes ORDER BY hostgroup_id"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_servers_ssl_params'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_SERVERS_SSL_PARAMS "PROXY_SELECT hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment FROM runtime_mysql_servers_ssl_params ORDER BY hostname, port, username"

/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_aws_aurora_hostgroups'. See top comment for details. */
#define CLUSTER_QUERY_MYSQL_AWS_AURORA "PROXY_SELECT writer_hostgroup, reader_hostgroup, active, aurora_port, domain_name, max_lag_ms, check_interval_ms, check_timeout_ms, writer_is_also_reader, new_reader_weight, add_lag_ms, min_lag_ms, lag_num_checks, comment FROM runtime_mysql_aws_aurora_hostgroups ORDER BY writer_hostgroup"

Expand Down Expand Up @@ -275,6 +278,8 @@ struct p_cluster_counter {
pulled_mysql_servers_aws_aurora_hostgroups_failure,
pulled_mysql_servers_hostgroup_attributes_success,
pulled_mysql_servers_hostgroup_attributes_failure,
pulled_mysql_servers_ssl_params_success,
pulled_mysql_servers_ssl_params_failure,
pulled_mysql_servers_runtime_checks_success,
pulled_mysql_servers_runtime_checks_failure,

Expand Down
5 changes: 5 additions & 0 deletions include/mysql_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ using json = nlohmann::json;
#define STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT 0x00000800
#define STATUS_MYSQL_CONNECTION_HAS_WARNINGS 0x00001000

class MySQLServers_SslParams;

class Variable {
public:
char *value = (char*)"";
Expand Down Expand Up @@ -151,6 +153,9 @@ class MySQL_Connection {
bool unknown_transaction_status;
void compute_unknown_transaction_status();
char gtid_uuid[128];

MySQLServers_SslParams * ssl_params = NULL;

MySQL_Connection();
~MySQL_Connection();
bool set_autocommit(bool);
Expand Down
3 changes: 2 additions & 1 deletion include/proxysql_admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ struct incoming_servers_t {
SQLite3_result* incoming_galera_hostgroups = NULL;
SQLite3_result* incoming_aurora_hostgroups = NULL;
SQLite3_result* incoming_hostgroup_attributes = NULL;
SQLite3_result* incoming_mysql_servers_ssl_params = NULL;

incoming_servers_t();
incoming_servers_t(SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*);
incoming_servers_t(SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*, SQLite3_result*);
};

// Separate structs for runtime mysql server and mysql server v2 to avoid human error
Expand Down
88 changes: 88 additions & 0 deletions lib/MySQL_HostGroups_Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,7 @@ MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() {
mydb->execute(MYHGM_MYSQL_GALERA_HOSTGROUPS);
mydb->execute(MYHGM_MYSQL_AWS_AURORA_HOSTGROUPS);
mydb->execute(MYHGM_MYSQL_HOSTGROUP_ATTRIBUTES);
mydb->execute(MYHGM_MYSQL_SERVERS_SSL_PARAMS);
mydb->execute("CREATE INDEX IF NOT EXISTS idx_mysql_servers_hostname_port ON mysql_servers (hostname,port)");
MyHostGroups=new PtrArray();
runtime_mysql_servers=NULL;
Expand All @@ -1361,6 +1362,7 @@ MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() {
incoming_galera_hostgroups=NULL;
incoming_aws_aurora_hostgroups = NULL;
incoming_hostgroup_attributes = NULL;
incoming_mysql_servers_ssl_params = NULL;
incoming_mysql_servers_v2 = NULL;
pthread_rwlock_init(&gtid_rwlock, NULL);
gtid_missing_nodes = false;
Expand Down Expand Up @@ -1631,6 +1633,7 @@ void MySQL_HostGroups_Manager::commit_update_checksums_from_tables(SpookyHash& m
CUCFT1(myhash,init,"mysql_galera_hostgroups","writer_hostgroup", table_resultset_checksum[HGM_TABLES::MYSQL_GALERA_HOSTGROUPS]);
CUCFT1(myhash,init,"mysql_aws_aurora_hostgroups","writer_hostgroup", table_resultset_checksum[HGM_TABLES::MYSQL_AWS_AURORA_HOSTGROUPS]);
CUCFT1(myhash,init,"mysql_hostgroup_attributes","hostgroup_id", table_resultset_checksum[HGM_TABLES::MYSQL_HOSTGROUP_ATTRIBUTES]);
CUCFT1(myhash,init,"mysql_servers_ssl_params","hostname,port,username", table_resultset_checksum[HGM_TABLES::MYSQL_SERVERS_SSL_PARAMS]);
}

/**
Expand Down Expand Up @@ -2162,6 +2165,13 @@ bool MySQL_HostGroups_Manager::commit(
generate_mysql_hostgroup_attributes_table();
}

// SSL params
if (incoming_mysql_servers_ssl_params) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "DELETE FROM mysql_servers_ssl_params\n");
mydb->execute("DELETE FROM mysql_servers_ssl_params");
generate_mysql_servers_ssl_params_table();
}

uint64_t new_hash = commit_update_checksum_from_mysql_servers_v2(peer_mysql_servers_v2.resultset);

{
Expand Down Expand Up @@ -2794,6 +2804,8 @@ SQLite3_result * MySQL_HostGroups_Manager::dump_table_mysql(const string& name)
query=(char *)"SELECT writer_hostgroup, reader_hostgroup, check_type, comment FROM mysql_replication_hostgroups";
} else if (name == "mysql_hostgroup_attributes") {
query=(char *)"SELECT hostgroup_id, max_num_online_servers, autocommit, free_connections_pct, init_connect, multiplex, connection_warming, throttle_connections_per_sec, ignore_session_variables, hostgroup_settings, servers_defaults, comment FROM mysql_hostgroup_attributes ORDER BY hostgroup_id";
} else if (name == "mysql_servers_ssl_params") {
query=(char *)"SELECT hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment FROM mysql_servers_ssl_params ORDER BY hostname, port, username";
} else if (name == "mysql_servers") {
query = (char *)MYHGM_GEN_ADMIN_RUNTIME_SERVERS;
} else if (name == "cluster_mysql_servers") {
Expand Down Expand Up @@ -4074,6 +4086,8 @@ void MySQL_HostGroups_Manager::save_incoming_mysql_table(SQLite3_result *s, cons
inc = &incoming_replication_hostgroups;
} else if (name == "mysql_hostgroup_attributes") {
inc = &incoming_hostgroup_attributes;
} else if (name == "mysql_servers_ssl_params") {
inc = &incoming_mysql_servers_ssl_params;
} else {
assert(0);
}
Expand Down Expand Up @@ -4111,6 +4125,8 @@ SQLite3_result* MySQL_HostGroups_Manager::get_current_mysql_table(const string&
return this->incoming_replication_hostgroups;
} else if (name == "mysql_hostgroup_attributes") {
return this->incoming_hostgroup_attributes;
} else if (name == "mysql_servers_ssl_params") {
return this->incoming_mysql_servers_ssl_params;
} else if (name == "cluster_mysql_servers") {
return this->runtime_mysql_servers;
} else if (name == "mysql_servers_v2") {
Expand Down Expand Up @@ -7337,6 +7353,60 @@ void MySQL_HostGroups_Manager::generate_mysql_hostgroup_attributes_table() {
incoming_hostgroup_attributes=NULL;
}

void MySQL_HostGroups_Manager::generate_mysql_servers_ssl_params_table() {
if (incoming_mysql_servers_ssl_params==NULL) {
return;
}
int rc;
sqlite3_stmt *statement=NULL;

const char * query = (const char *)"INSERT INTO mysql_servers_ssl_params ("
"hostname, port, username, ssl_ca, ssl_cert, ssl_key, ssl_capath, "
"ssl_crl, ssl_crlpath, ssl_cipher, tls_version, comment) VALUES "
"(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)";

rc = mydb->prepare_v2(query, &statement);
ASSERT_SQLITE_OK(rc, mydb);
proxy_info("New mysql_servers_ssl_params table\n");
std::lock_guard<std::mutex> lock(Servers_SSL_Params_map_mutex);
Servers_SSL_Params_map.clear();

for (std::vector<SQLite3_row *>::iterator it = incoming_mysql_servers_ssl_params->rows.begin() ; it != incoming_mysql_servers_ssl_params->rows.end(); ++it) {
SQLite3_row *r=*it;
proxy_info("Loading MySQL Server SSL Params for (%s,%s,%s)\n",
r->fields[0], r->fields[1], r->fields[2]
);

rc=(*proxy_sqlite3_bind_text)(statement, 1, r->fields[0] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // hostname
rc=(*proxy_sqlite3_bind_int64)(statement, 2, atoi(r->fields[1])); ASSERT_SQLITE_OK(rc, mydb); // port
rc=(*proxy_sqlite3_bind_text)(statement, 3, r->fields[2] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // username
rc=(*proxy_sqlite3_bind_text)(statement, 4, r->fields[3] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_ca
rc=(*proxy_sqlite3_bind_text)(statement, 5, r->fields[4] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_cert
rc=(*proxy_sqlite3_bind_text)(statement, 6, r->fields[5] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_key
rc=(*proxy_sqlite3_bind_text)(statement, 7, r->fields[6] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_capath
rc=(*proxy_sqlite3_bind_text)(statement, 8, r->fields[7] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_crl
rc=(*proxy_sqlite3_bind_text)(statement, 9, r->fields[8] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_crlpath
rc=(*proxy_sqlite3_bind_text)(statement, 10, r->fields[9] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // ssl_cipher
rc=(*proxy_sqlite3_bind_text)(statement, 11, r->fields[10] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // tls_version
rc=(*proxy_sqlite3_bind_text)(statement, 12, r->fields[11] , -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); // comment

SAFE_SQLITE3_STEP2(statement);
rc=(*proxy_sqlite3_clear_bindings)(statement); ASSERT_SQLITE_OK(rc, mydb);
rc=(*proxy_sqlite3_reset)(statement); ASSERT_SQLITE_OK(rc, mydb);

MySQLServers_SslParams MSSP(
r->fields[0], atoi(r->fields[1]), r->fields[2],
r->fields[3], r->fields[4], r->fields[5],
r->fields[6], r->fields[7], r->fields[8],
r->fields[9], r->fields[10], r->fields[11]
);
string MapKey = MSSP.getMapKey(rand_del);
Servers_SSL_Params_map.emplace(MapKey, MSSP);
}
delete incoming_mysql_servers_ssl_params;
incoming_mysql_servers_ssl_params=NULL;
}

void MySQL_HostGroups_Manager::generate_mysql_aws_aurora_hostgroups_table() {
if (incoming_aws_aurora_hostgroups==NULL) {
return;
Expand Down Expand Up @@ -8182,3 +8252,21 @@ void MySQL_HostGroups_Manager::HostGroup_Server_Mapping::remove_HGM(MySrvC* srv)
srv->status = MYSQL_SERVER_STATUS_OFFLINE_HARD;
srv->ConnectionsFree->drop_all_connections();
}

MySQLServers_SslParams * MySQL_HostGroups_Manager::get_Server_SSL_Params(char *hostname, int port, char *username) {
string MapKey = string(hostname) + string(rand_del) + to_string(port) + string(rand_del) + string(username);
std::lock_guard<std::mutex> lock(Servers_SSL_Params_map_mutex);
auto it = Servers_SSL_Params_map.find(MapKey);
if (it != Servers_SSL_Params_map.end()) {
MySQLServers_SslParams * MSSP = new MySQLServers_SslParams(it->second);
return MSSP;
} else {
MapKey = string(hostname) + string(rand_del) + to_string(port) + string(rand_del) + ""; // search for empty username
it = Servers_SSL_Params_map.find(MapKey);
if (it != Servers_SSL_Params_map.end()) {
MySQLServers_SslParams * MSSP = new MySQLServers_SslParams(it->second);
return MSSP;
}
}
return NULL;
}
Loading

0 comments on commit 8a4246d

Please sign in to comment.