Revert "T87 Consul integration"

pull/506/head
Ionut Prunache 10 years ago
parent c623a6b4d9
commit 50b3e3191b

3
.gitignore vendored

@ -29,9 +29,6 @@ oldcode/tests/connect_speed
*.swp
# CTags
.tags
.tags_sorted_by_file
# SQLITE files
*.db

@ -168,7 +168,7 @@ cleanall:
rm binaries/*deb || true
rm binaries/*rpm || true
install: src/proxysql install-proxysql-consul
install: src/proxysql
install -m 0755 src/proxysql /usr/local/bin
install -m 0600 etc/proxysql.cnf /etc
install -m 0755 etc/init.d/proxysql /etc/init.d
@ -176,20 +176,10 @@ install: src/proxysql install-proxysql-consul
update-rc.d proxysql defaults
.PHONY: install
install-proxysql-consul:
install -m 0755 integrations/consul/proxysql-consul /usr/local/bin
install -m 0600 integrations/consul/proxysql-consul.cnf /etc
.PHONY: install-proxysql-consul
uninstall: uninstall-proxysql-consul
uninstall:
rm /etc/init.d/proxysql
rm /etc/proxysql.cnf
rm /usr/local/bin/proxysql
rmdir /var/lib/proxysql 2>/dev/null || true
update-rc.d proxysql remove
.PHONY: uninstall
uninstall-proxysql-consul:
rm /usr/local/bin/proxysql-consul
rm /etc/proxysql-consul.cnf
.PHONY: uninstall-proxysql-consul

@ -112,16 +112,12 @@ class ProxySQL_Admin {
void flush_mysql_servers__from_memory_to_disk();
void flush_mysql_servers__from_disk_to_memory();
void flush_mysql_query_rules__from_memory_to_disk();
void flush_mysql_query_rules__from_disk_to_memory();
bool save_mysql_query_rules_to_cluster();
void flush_mysql_query_rules__from_disk_to_memory();
void load_mysql_servers_to_runtime();
void save_mysql_servers_from_runtime();
bool save_mysql_servers_to_cluster();
char * load_mysql_query_rules_to_runtime();
void save_mysql_query_rules_from_runtime(bool);
int save_config_to_cluster(char *tablename);
void load_admin_variables_to_runtime() { flush_admin_variables___database_to_runtime(admindb, true); }
void save_admin_variables_from_runtime() { flush_admin_variables___runtime_to_database(admindb, true, true, false); }

@ -1,9 +0,0 @@
{
"watches": [
{
"type": "keyprefix",
"prefix": "proxysql/",
"handler": "proxysql-consul update"
}
]
}

@ -1,51 +0,0 @@
proxysql-consul writes table contents read from ProxySQL's admin interface to Consul's key/value store. proxysql-consul uses one key for each table and each key is prefixed with 'proxysql' so that all ProxySQL keys live in their own namespace.
Example:
```
key: proxysql/mysql_servers
```
The value written is a JSON with multiple fields:
- table - the name of the table.
- uuid - unique identifier of the proxysql-consul instance.
- rows - content of the table as an array of rows. Each row is an array of string values.
Example:
```
{
"table":"mysql_servers",
"rows":[
[
"0",
"127.0.0.1",
"3306",
"ONLINE",
"1",
"0",
"1000",
"10"
],
[
"0",
"/var/lib/mysql/mysql.sock",
"0",
"ONLINE",
"1",
"0",
"1000",
"0"
]
],
"uuid":"aae13abd-2a76-4882-afd3-0b2369e02b07"
}
```
The value corresponds to the following mysql_servers dump:
```
+--------------+---------------------------+------+--------+--------+-------------+-----------------+---------------------+
| hostgroup_id | hostname | port | status | weight | compression | max_connections | max_replication_lag |
+--------------+---------------------------+------+--------+--------+-------------+-----------------+---------------------+
| 0 | 127.0.0.1 | 3306 | ONLINE | 1 | 0 | 1000 | 10 |
| 0 | /var/lib/mysql/mysql.sock | 0 | ONLINE | 1 | 0 | 1000 | 0 |
+--------------+---------------------------+------+--------+--------+-------------+-----------------+---------------------+
```

@ -1,217 +0,0 @@
#!/usr/bin/env python
"""
Usage:
proxysql-consul put <table> [--config-file=<config-file>]
proxysql-consul update [--config-file=<config-file>]
proxysql-consul (-h | --help)
Options:
-h --help
Show this screen.
--config-file=<config-file>
Path to config file [default: /etc/proxysql-consul.cnf].
"""
from docopt import docopt
import base64
import json
import os
import requests
import sys
import uuid
import MySQLdb
CFG_PATH = '/etc/proxysql-consul.cnf'
CFG_UUID_FILE = 'uuid_file'
CFG_UUID = 'uuid'
CFG_CONSUL_IFACE = 'consul_iface'
CFG_CONSUL_PORT = 'consul_port'
CFG_PROXY_IFACE = 'proxysql_admin_iface'
CFG_PROXY_PORT = 'proxysql_admin_port'
CFG_PROXY_USERNAME = 'proxysql_admin_username'
CFG_PROXY_PASSWORD = 'proxysql_admin_password'
# Proxysql config types to Consul key mapping
TABLE_TO_KEY = {
'mysql_servers': 'proxysql/mysql_servers',
'mysql_query_rules': 'proxysql/mysql_query_rules'
}
SAVE_QUERY_BY_TABLE = {
'mysql_servers': 'SAVE MYSQL SERVERS TO MEMORY',
'mysql_query_rules': 'SAVE MYSQL QUERY RULES TO MEMORY'
}
LOAD_QUERY_BY_TABLE = {
'mysql_servers': 'LOAD MYSQL SERVERS FROM MEMORY',
'mysql_query_rules': 'LOAD MYSQL QUERY RULES FROM MEMORY'
}
config = {}
def read_config_from_file():
global config
with open(CFG_PATH) as config_file:
config_data = config_file.read()
config = json.loads(config_data)
# TODO(ipruanche) validate config
def read_uuid_from_file():
"""
Reads the UUID identifying this script instance from a file store. If the
file does not exist creates it and writes a new UUID.
Puts the UUID in the config dictionary.
"""
uuid_file_path = config[CFG_UUID_FILE]
if not os.path.isfile(uuid_file_path):
_uuid = str(uuid.uuid4())
with open(uuid_file_path, 'w') as uuid_file:
uuid_file.write(_uuid)
else:
with open(uuid_file_path, 'r') as uuid_file:
_uuid = uuid_file.read()
config[CFG_UUID] = _uuid
def fetch_proxysql_config(table):
admin_connection = MySQLdb.connect(config[CFG_PROXY_IFACE],
config[CFG_PROXY_USERNAME],
config[CFG_PROXY_PASSWORD],
port=config[CFG_PROXY_PORT],
db='main')
# save runtime config to memory so we can read them
cursor = admin_connection.cursor()
save_query = SAVE_QUERY_BY_TABLE[table]
cursor.execute(save_query)
cursor.close()
# read runtime config from memory
cursor = admin_connection.cursor()
cursor.execute('SELECT * FROM %s' % table)
rows = cursor.fetchall()
cursor.close()
admin_connection.close()
return rows
def put_config_to_consul(table):
if table not in TABLE_TO_KEY:
print 'Unknown config table. Exiting.'
exit(1)
rows = fetch_proxysql_config(table)
consul_data = {}
consul_data['table'] = table
consul_data['rows'] = rows
consul_data['uuid'] = config[CFG_UUID]
consul_data_json = json.dumps(consul_data)
key = TABLE_TO_KEY[table]
consul_iface = config[CFG_CONSUL_IFACE]
consul_port = config[CFG_CONSUL_PORT]
url = 'http://%s:%s/v1/kv/%s' % (consul_iface, consul_port, key)
r = requests.put(url, data=consul_data_json)
r.raise_for_status()
print 'Configs pushed successfully.'
def build_multivalue_insert(table, rows):
# add quotes arround all values to make them strings in the sql query
quoted_values = [['"' + x + '"' for x in row] for row in rows]
# join each row in a values() group
row_join = [','.join(x) for x in quoted_values]
query = 'INSERT INTO %s VALUES(%s)' % (table, '),('.join(row_join))
return query
def update_proxysql_runtime_config(table, rows):
admin_connection = MySQLdb.connect(config[CFG_PROXY_IFACE],
config[CFG_PROXY_USERNAME],
config[CFG_PROXY_PASSWORD],
port=config[CFG_PROXY_PORT],
db='main')
# clear table
cursor = admin_connection.cursor()
cursor.execute('DELETE FROM %s' % table)
cursor.close()
# insert values from Consul
insert_query = build_multivalue_insert(table, rows)
cursor = admin_connection.cursor()
cursor.execute(insert_query)
cursor.close()
# commit changes to runtine
load_query = LOAD_QUERY_BY_TABLE[table]
cursor = admin_connection.cursor()
cursor.execute(load_query)
cursor.close()
admin_connection.close()
def update_config():
"""
Reads all input from stdin that is passed by Consul and extracts the config
that was modified.
Consul is configured to watch all proxysql keys and returns all their values
when one key is modified. To determine the value that was actually modified
we use the CONSUL_INDEX env var written by Consul. This should match the
'ModifyIndex' field of the value that triggered the watch.
Values are returned as a JSON array. The actual value content is stored in
the 'Value' field, base64 encoded.
"""
if 'CONSUL_INDEX' not in os.environ:
print 'Missing consul index on update request'
exit(1)
consul_index = int(os.environ['CONSUL_INDEX'])
consul_data = sys.stdin.read()
updated_value = None
values = json.loads(consul_data)
for value in values:
if 'ModifyIndex' in value and value['ModifyIndex'] == consul_index:
updated_value = value
break
if not updated_value:
print 'Failed to determine updated config from Consul data'
exit(1)
proxysql_config_json = base64.b64decode(updated_value['Value'])
proxysql_config = json.loads(proxysql_config_json)
table = proxysql_config['table']
rows = proxysql_config['rows']
_uuid = proxysql_config['uuid']
if not rows:
print 'Empty config set for table: %s.' % table
return
if _uuid == config[CFG_UUID]:
print 'Ignoring self update.'
return
update_proxysql_runtime_config(table, rows)
print 'Configs updated successfully.'
if __name__ == '__main__':
arguments = docopt(__doc__, version='proxysql-consul 1.0')
read_config_from_file()
read_uuid_from_file()
if arguments['put']:
put_config_to_consul(arguments['<table>'])
elif arguments['update']:
update_config()

@ -1,9 +0,0 @@
{
"uuid_file": "/var/lib/proxysql/proxysql-consul.uuid",
"consul_iface": "127.0.0.1",
"consul_port": "8500",
"proxysql_admin_iface": "127.0.0.1",
"proxysql_admin_port": 6032,
"proxysql_admin_username": "admin",
"proxysql_admin_password": "admin"
}

@ -1,13 +1,10 @@
#include "proxysql.h"
#include "cpp.h"
#include <errno.h>
#include <search.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <assert.h>
@ -797,19 +794,6 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
if (query_no_space_length==strlen("SAVE MYSQL SERVERS TO CLUSTER") && !strncasecmp("SAVE MYSQL SERVERS TO CLUSTER", query_no_space, query_no_space_length)) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Pushed mysql servers from RUNTIME to cluster\n");
bool success = SPA->save_mysql_servers_to_cluster();
if (success) {
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
} else {
SPA->send_MySQL_ERR(&sess->client_myds->myprot, NULL);
}
return false;
}
}
if ((query_no_space_length>23) && ( (!strncasecmp("SAVE MYSQL QUERY RULES ", query_no_space, 23)) || (!strncasecmp("LOAD MYSQL QUERY RULES ", query_no_space, 23))) ) {
@ -909,19 +893,6 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
if (query_no_space_length==strlen("SAVE MYSQL QUERY RULES TO CLUSTER") && !strncasecmp("SAVE MYSQL QUERY RULES TO CLUSTER", query_no_space, query_no_space_length)) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Pushed mysql query rules from RUNTIME to cluster\n");
bool success = SPA->save_mysql_query_rules_to_cluster();
if (success) {
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
} else {
SPA->send_MySQL_ERR(&sess->client_myds->myprot, NULL);
}
return false;
}
}
if ((query_no_space_length>21) && ( (!strncasecmp("SAVE ADMIN VARIABLES ", query_no_space, 21)) || (!strncasecmp("LOAD ADMIN VARIABLES ", query_no_space, 21))) ) {
@ -3467,50 +3438,6 @@ void ProxySQL_Admin::load_mysql_servers_to_runtime() {
}
// Gets a copy of the runtime mysql servers config and passes is to an external script for distribution
// to other ProxySQL instances. Returns true in case of success and false in case of failure.
bool ProxySQL_Admin::save_mysql_servers_to_cluster() {
char *tablename = (char *)"mysql_servers";
int status_code = save_config_to_cluster(tablename);
return status_code == 0;
}
// Gets a copy of the runtime mysql query rules config and passes is to an external script for distribution
// to other ProxySQL instances. Returns true in case of success and false in case of failure.
bool ProxySQL_Admin::save_mysql_query_rules_to_cluster() {
char *tablename = (char *)"mysql_query_rules";
int status_code = save_config_to_cluster(tablename);
return status_code == 0;
}
// Runs external config distribution script passing it the given table name. The script will use the admin
// interface to read the contents of the table.
int ProxySQL_Admin::save_config_to_cluster(char *tablename) {
pid_t pid = fork();
if (pid == 0) {
// child
errno = 0;
int exec_status = execlp("/usr/local/bin/proxysql-consul", "/usr/local/bin/proxysql-consul", "put", tablename, (char *) 0);
if (exec_status == -1) {
proxy_error("Exec failed for config save script with errno: %d.\n", errno);
}
_exit(0);
} else if (pid < 0) {
// failed to fork
proxy_error("Failed to fork for saving config.\n");
return -1;
} else {
// parent
int status_code;
waitpid(pid, &status_code, 0);
if (!WIFEXITED(status_code)) {
proxy_error("Config save script exited with an error: %d.\n", WEXITSTATUS(status_code));
}
proxy_info("Config save script exited with status code: %d.\n", status_code);
return status_code;
}
}
char * ProxySQL_Admin::load_mysql_query_rules_to_runtime() {
char *error=NULL;
int cols=0;

Loading…
Cancel
Save