From 99abb48c2120c4a27512e409d682f9d2ec77bc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 9 Sep 2016 08:28:48 +0000 Subject: [PATCH] Implementation of runtime_mysql_users #691 --- include/proxysql_admin.h | 2 +- lib/ProxySQL_Admin.cpp | 49 +++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/proxysql_admin.h b/include/proxysql_admin.h index f1f645e4b..54be571e3 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -147,7 +147,7 @@ class ProxySQL_Admin { void init_users(); void init_mysql_servers(); void init_mysql_query_rules(); - void save_mysql_users_runtime_to_database(); + void save_mysql_users_runtime_to_database(bool _runtime); void save_mysql_servers_runtime_to_database(bool); void admin_shutdown(); bool is_command(std::string); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 4c68587c3..74aac25ab 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -89,6 +89,9 @@ pthread_mutex_t admin_mutex = PTHREAD_MUTEX_INITIALIZER; #define ADMIN_SQLITE_TABLE_MYSQL_SERVERS_V1_2_2 "CREATE TABLE mysql_servers (hostgroup_id INT NOT NULL DEFAULT 0 , hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , status VARCHAR CHECK (UPPER(status) IN ('ONLINE','SHUNNED','OFFLINE_SOFT', 'OFFLINE_HARD')) NOT NULL DEFAULT 'ONLINE' , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 1 , compression INT CHECK (compression >=0 AND compression <= 102400) NOT NULL DEFAULT 0 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 1000 , max_replication_lag INT CHECK (max_replication_lag >= 0 AND max_replication_lag <= 126144000) NOT NULL DEFAULT 0 , use_ssl INT CHECK (use_ssl IN(0,1)) NOT NULL DEFAULT 0 , max_latency_ms INT UNSIGNED CHECK (max_latency_ms>=0) NOT NULL DEFAULT 0 , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostgroup_id, hostname, port) )" #define ADMIN_SQLITE_TABLE_MYSQL_USERS "CREATE TABLE mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 0 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" + +#define ADMIN_SQLITE_RUNTIME_MYSQL_USERS "CREATE TABLE runtime_mysql_users (username VARCHAR NOT NULL , password VARCHAR , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0 , default_hostgroup INT NOT NULL DEFAULT 0 , default_schema VARCHAR , schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0 , transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 0 , fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0 , backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1 , frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000 , PRIMARY KEY (username, backend) , UNIQUE (username, frontend))" + #define ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES "CREATE TABLE mysql_query_rules (rule_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 0 , username VARCHAR , schemaname VARCHAR , flagIN INT NOT NULL DEFAULT 0 , client_addr VARCHAR , proxy_addr VARCHAR , proxy_port INT , digest VARCHAR , match_digest VARCHAR , match_pattern VARCHAR , negate_match_pattern INT CHECK (negate_match_pattern IN (0,1)) NOT NULL DEFAULT 0 , flagOUT INT , replace_pattern VARCHAR , destination_hostgroup INT DEFAULT NULL , cache_ttl INT CHECK(cache_ttl > 0) , reconnect INT CHECK (reconnect IN (0,1)) DEFAULT NULL , timeout INT UNSIGNED , retries INT CHECK (retries>=0 AND retries <=1000) , delay INT UNSIGNED , mirror_flagOUT INT UNSIGNED , mirror_hostgroup INT UNSIGNED , error_msg VARCHAR , log INT CHECK (log IN (0,1)) , apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0 , comment VARCHAR)" // mysql_query_rules in v1.1.0 @@ -825,7 +828,7 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query ) { proxy_info("Received %s command\n", query_no_space); ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa; - SPA->save_mysql_users_runtime_to_database(); + SPA->save_mysql_users_runtime_to_database(false); proxy_debug(PROXY_DEBUG_ADMIN, 4, "Saved mysql users from RUNTIME\n"); SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL); return false; @@ -1206,6 +1209,7 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign bool dump_global_variables=false; bool runtime_scheduler=false; + bool runtime_mysql_users=false; bool runtime_mysql_servers=false; bool runtime_mysql_query_rules=false; @@ -1238,6 +1242,9 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign ) { runtime_mysql_servers=true; refresh=true; } + if (strstr(query_no_space,"runtime_mysql_users")) { + runtime_mysql_users=true; refresh=true; + } if (strstr(query_no_space,"runtime_mysql_query_rules")) { runtime_mysql_query_rules=true; refresh=true; } @@ -1275,6 +1282,9 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign save_mysql_servers_runtime_to_database(true); mysql_servers_wrunlock(); } + if (runtime_mysql_users) { + save_mysql_users_runtime_to_database(true); + } if (runtime_mysql_query_rules) { save_mysql_query_rules_from_runtime(true); } @@ -2477,6 +2487,7 @@ bool ProxySQL_Admin::init() { insert_into_tables_defs(tables_defs_admin,"mysql_servers", ADMIN_SQLITE_TABLE_MYSQL_SERVERS); insert_into_tables_defs(tables_defs_admin,"runtime_mysql_servers", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_SERVERS); insert_into_tables_defs(tables_defs_admin,"mysql_users", ADMIN_SQLITE_TABLE_MYSQL_USERS); + insert_into_tables_defs(tables_defs_admin,"runtime_mysql_users", ADMIN_SQLITE_RUNTIME_MYSQL_USERS); insert_into_tables_defs(tables_defs_admin,"runtime_mysql_replication_hostgroups", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_REPLICATION_HOSTGROUPS); insert_into_tables_defs(tables_defs_admin,"mysql_replication_hostgroups", ADMIN_SQLITE_TABLE_MYSQL_REPLICATION_HOSTGROUPS); insert_into_tables_defs(tables_defs_admin,"mysql_query_rules", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES); @@ -3773,7 +3784,7 @@ void ProxySQL_Admin::__add_active_users(enum cred_username_type usertype) { } -void ProxySQL_Admin::save_mysql_users_runtime_to_database() { +void ProxySQL_Admin::save_mysql_users_runtime_to_database(bool _runtime) { /* char *error=NULL; int cols=0; @@ -3788,32 +3799,48 @@ void ProxySQL_Admin::save_mysql_users_runtime_to_database() { } if(resultset) delete resultset; */ - char *qd=(char *)"UPDATE mysql_users SET active=0"; - proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", qd); - admindb->execute(qd); + char *query=NULL; + if (_runtime) { + query=(char *)"DELETE FROM main.runtime_mysql_users"; + admindb->execute(query); + } else { + char *qd=(char *)"UPDATE mysql_users SET active=0"; + proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", qd); + admindb->execute(qd); + } account_details_t **ads=NULL; int num_users; int i; char *qf=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES(\"%s\",\"%s\",1,%d,%d,\"%s\",%d,%d,%d,COALESCE((SELECT backend FROM mysql_users WHERE username=\"%s\" AND frontend=1),0),1,%d)"; char *qb=(char *)"REPLACE INTO mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES(\"%s\",\"%s\",1,%d,%d,\"%s\",%d,%d,%d,1,COALESCE((SELECT frontend FROM mysql_users WHERE username=\"%s\" AND backend=1),0),%d)"; + char *qfr=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES(\"%s\",\"%s\",1,%d,%d,\"%s\",%d,%d,%d,COALESCE((SELECT backend FROM runtime_mysql_users WHERE username=\"%s\" AND frontend=1),0),1,%d)"; + char *qbr=(char *)"REPLACE INTO runtime_mysql_users(username,password,active,use_ssl,default_hostgroup,default_schema,schema_locked,transaction_persistent,fast_forward,backend,frontend,max_connections) VALUES(\"%s\",\"%s\",1,%d,%d,\"%s\",%d,%d,%d,1,COALESCE((SELECT frontend FROM runtime_mysql_users WHERE username=\"%s\" AND backend=1),0),%d)"; num_users=GloMyAuth->dump_all_users(&ads); if (num_users==0) return; for (i=0; iusername, ads[i]->default_hostgroup); account_details_t *ad=ads[i]; if (ads[i]->default_hostgroup >= 0) { - char *query; - char *q; - if (ad->__frontend) { - q=qf; - } else { - q=qb; + char *q=NULL; + if (_runtime==false) { + if (ad->__frontend) { + q=qf; + } else { + q=qb; + } + } else { // _runtime==true + if (ad->__frontend) { + q=qfr; + } else { + q=qbr; + } } query=(char *)malloc(strlen(q)+strlen(ad->username)*2+strlen(ad->password)+strlen(ad->default_schema)+256); sprintf(query, q, ad->username, ad->password, ad->use_ssl, ad->default_hostgroup, ad->default_schema, ad->schema_locked, ad->transaction_persistent, ad->fast_forward, ad->username, ad->max_connections); //fprintf(stderr,"%s\n",query); proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query); admindb->execute(query); + free(query); } free(ad->username); free(ad->password);