Remove old feedback system

The feedback system wasn't used and was starting to cause problems on
Debian 9 where the libcurl required different version of OpenSSL than what
MaxScale was linked against.
This commit is contained in:
Markus Mäkelä
2017-07-08 05:18:47 +03:00
parent 33e1878fe1
commit 61241f9e07
15 changed files with 9 additions and 944 deletions

View File

@ -14,8 +14,8 @@ then
sudo apt-get install -y --force-yes dpkg-dev git wget \
build-essential libssl-dev ncurses-dev bison flex \
perl libtool libcurl4-openssl-dev libpcre3-dev tcl tcl-dev uuid \
uuid-dev libsqlite3-dev
perl libtool libpcre3-dev tcl tcl-dev uuid \
uuid-dev libsqlite3-dev
## separatelibgnutls installation process for Ubuntu Trusty
cat /etc/*release | grep "Trusty"
if [ $? == 0 ]
@ -41,7 +41,7 @@ else
then
# We need zypper here
sudo zypper -n install gcc gcc-c++ ncurses-devel bison glibc-devel libgcc_s1 perl \
make libtool libopenssl-devel libaio libaio-devel flex libcurl-devel \
make libtool libopenssl-devel libaio libaio-devel flex \
pcre-devel git wget tcl libuuid-devel \
xz-devel sqlite3 sqlite3-devel pkg-config lua lua-devel \
gnutls-devel libgcrypt-devel
@ -57,7 +57,7 @@ else
sudo yum clean all
sudo yum install -y --nogpgcheck gcc gcc-c++ ncurses-devel bison glibc-devel \
libgcc perl make libtool openssl-devel libaio libaio-devel libedit-devel \
libedit-devel libcurl-devel curl-devel systemtap-sdt-devel rpm-sign wget \
libedit-devel systemtap-sdt-devel rpm-sign wget \
gnupg pcre-devel flex rpmdevtools git wget tcl openssl libuuid-devel xz-devel \
sqlite sqlite-devel pkgconfig lua lua-devel rpm-build createrepo yum-utils \
gnutls-devel libgcrypt-devel

View File

@ -38,7 +38,6 @@ find_package(Pandoc)
find_package(TCMalloc)
find_package(Jemalloc)
find_package(Git)
find_package(CURL)
find_package(RabbitMQ)
find_package(LibUUID)
find_package(Avro)
@ -66,13 +65,6 @@ include(cmake/BuildMicroHttpd.cmake)
include_directories(${JANSSON_INCLUDE_DIR})
# You can find the variables set by this in the FindCURL.cmake file
# which is a default module in CMake.
if(NOT CURL_FOUND)
message(FATAL_ERROR "Failed to locate dependency: libcurl")
endif()
if(NOT OPENSSL_FOUND)
message(FATAL_ERROR "Failed to locate dependency: OpenSSL")
else()

View File

@ -6,7 +6,6 @@ requirements are as follows:
* CMake version 2.8 or later (Packaging requires version 2.8.12 or later)
* GCC version 4.4.7 or later
* SQLite3 version 3.3 or later
* libcurl
* OpenSSL
* Bison 2.7 or later
* Flex 2.5.35 or later
@ -23,7 +22,7 @@ CentOS 7:
```
sudo yum install git gcc gcc-c++ ncurses-devel bison flex glibc-devel cmake \
libgcc perl make libtool openssl openssl-devel libcurl-devel pcre-devel \
libgcc perl make libtool openssl openssl-devel pcre-devel \
tcl tcl-devel systemtap-sdt-devel libuuid libuuid-devel sqlite sqlite-devel \
gnutls-devel libgcrypt-devel
```
@ -33,7 +32,7 @@ Ubuntu 16.04:
```
sudo apt-get update
sudo apt-get install git build-essential libssl-dev ncurses-dev bison flex \
cmake perl libtool libcurl4-openssl-dev libpcre3-dev tcl tcl-dev uuid \
cmake perl libtool libpcre3-dev tcl tcl-dev uuid \
uuid-dev libsqlite3-dev gnutls-dev libgcrypt20-dev
```
@ -58,7 +57,7 @@ other packages in addition to these.
```
git gcc gcc-c++ ncurses-devel bison flex glibc-devel cmake libgcc perl make \
libtool openssl openssl-devel libcurl-devel pcre-devel tcl tcl-devel \
libtool openssl openssl-devel pcre-devel tcl tcl-devel \
systemtap-sdt-devel libuuid libuuid-devel sqlite sqlite-devel
gnutls-devel libgcrypt-devel
```
@ -70,7 +69,7 @@ require other packages in addition to these.
```
git build-essential libssl-dev ncurses-dev bison flex cmake perl libtool \
libcurl4-openssl-dev libpcre3-dev tlc tcl-dev uuid uuid-dev sqlite3-dev
libpcre3-dev tlc tcl-dev uuid uuid-dev sqlite3-dev
libgnutls30 libgcrypt20
```

View File

@ -371,7 +371,6 @@ disable:
disable log-priority - Disable a logging priority
disable sessionlog-priority - [Deprecated] Disable a logging priority for a particular session
disable root - Disable root access
disable feedback - Disable MaxScale feedback to notification service
disable syslog - Disable syslog logging
disable maxlog - Disable MaxScale logging
disable account - Disable Linux user
@ -380,7 +379,6 @@ enable:
enable log-priority - Enable a logging priority
enable sessionlog-priority - [Deprecated] Enable a logging priority for a session
enable root - Enable root user access to a service
enable feedback - Enable MaxScale feedback to notification service
enable syslog - Enable syslog logging
enable maxlog - Enable MaxScale logging
enable account - Activate a Linux user account for MaxAdmin use
@ -423,7 +421,6 @@ show:
show authenticators - Show authenticator diagnostics for a service
show epoll - Show the polling system statistics
show eventstats - Show event queue statistics
show feedbackreport - Show the report of MaxScale loaded modules, suitable for Notification Service
show filter - Show filter details
show filters - Show all filters
show log_throttling - Show the current log throttling setting (count, window (ms), suppression (ms))

View File

@ -1,75 +0,0 @@
# MariaDB MaxScale Notification Service and Feedback Support
## Overview
The purpose of Notification Service in MariaDB MaxScale is for a customer registered for the service to receive update notices, security bulletins, fixes and workarounds that are tailored to the database server configuration.
## MariaDB MaxScale Setup
MariaDB MaxScale may collect the installed plugins and send the information's nightly, between 2:00 AM and 4:59 AM.
It tries to send data and if there is any failure (timeout, server is down, etc), the next retry is in 1800 seconds (30 minutes).
This feature is not enabled by default: MariaDB MaxScale must be configured in `[feedback]` section:
```
[feedback]
feedback_enable=1
feedback_url=https://enterprise.mariadb.com/feedback/post
feedback_user_info=x-y-z-w
```
The activation code that will be provided by MariaDB Corporation Ab upon request by the customer and it should be put in feedback_user_info.
Example:
```
feedback_user_info=0467009f-b04d-45b1-a77b-b6b2ec9c6cf4
```
MariaDB MaxScale generates the feedback report containing following information:
- The activation code used to enable feedback
- MariaDB MaxScale Version
- An identifier of the MariaDB MaxScale installation, i.e. the HEX encoding of SHA1 digest of the first network interface MAC address
- Operating System (i.e Linux)
- Operating System Distribution (i.e. CentOS release 6.5 (Final))
- All the modules in use in MariaDB MaxScale and their API and version
- MariaDB MaxScale server UNIX_TIME at generation time
MariaDB MaxScale shall send the generated feedback report to a feedback server specified in _feedback_url_.
## Manual Operation
If it’s not possible to send data due to firewall or security settings the report could be generated manually (feedback_user_info is required) via MaxAdmin.
```
MaxScale>show feedbackreport
```
Report could be saved to report.txt file:
```
$ maxadmin show feedbackreport > ./report.txt
curl -F data=@./report.txt https://mariadb.org/feedback_plugin/post
```
Report Example:
```
FEEDBACK_SERVER_UID 6B5C44AEA73137D049B02E6D1C7629EF431A350F
FEEDBACK_USER_INFO 0467009f-b04d-45b1-a77b-b6b2ec9c6cf4
VERSION 1.0.6-unstable
NOW 1425914890
PRODUCT maxscale
Uname_sysname Linux
Uname_distribution CentOS release 6.5 (Final)
module_maxscaled_type Protocol
module_maxscaled_version V1.0.0
module_maxscaled_api 1.0.0
module_maxscaled_releasestatus GA
module_telnetd_type Protocol
module_telnetd_version V1.0.1
module_telnetd_api 1.0.0
module_telnetd_releasestatus GA
```

View File

@ -96,7 +96,6 @@ extern const char CN_DATA[];
extern const char CN_DEFAULT[];
extern const char CN_DESCRIPTION[];
extern const char CN_ENABLE_ROOT_USER[];
extern const char CN_FEEDBACK[];
extern const char CN_FILTERS[];
extern const char CN_FILTER[];
extern const char CN_GATEWAY[];
@ -460,16 +459,6 @@ unsigned int config_nbpolls(void);
*/
unsigned int config_pollsleep(void);
/**
* @brief Enable feedback task
*/
void config_enable_feedback_task(void);
/**
* @brief Disable feedback task
*/
void config_disable_feedback_task(void);
/**
* @brief Reload the configuration
*

View File

@ -1,56 +0,0 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file notification.h
*
* The configuration stuct for notification/feedback service
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
#define _NOTIFICATION_CONNECT_TIMEOUT 30
#define _NOTIFICATION_OPERATION_TIMEOUT 30
#define _NOTIFICATION_SEND_PENDING 0
#define _NOTIFICATION_SEND_OK 1
#define _NOTIFICATION_SEND_ERROR 2
#define _NOTIFICATION_REPORT_ROW_LEN 255
#include <stdint.h>
/**
* The configuration and usage information data for feeback service
*/
typedef struct
{
int feedback_enable; /**< Enable/Disable Notification feedback */
char *feedback_url; /**< URL to which the data is sent */
char *feedback_user_info; /**< User info included in the feedback data sent */
int feedback_timeout; /**< An attempt to write/read the data times out and fails after this many seconds */
int feedback_connect_timeout;/**< An attempt to send the data times out and fails after this many seconds */
int feedback_last_action; /**< Holds the feedback last send action status */
int feedback_frequency; /*< Frequency of the housekeeper task */
char *release_info; /**< Operating system Release name */
char *sysname; /**< Operating system name */
uint8_t *mac_sha1; /**< First available MAC address*/
} FEEDBACK_CONF;
extern char *gw_bin2hex(char *out, const uint8_t *in, unsigned int len);
extern void gw_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
extern FEEDBACK_CONF * config_get_feedback_data();
MXS_END_DECLS

View File

@ -65,7 +65,6 @@ target_link_libraries(maxscale-common
${MARIADB_CONNECTOR_LIBRARIES}
${LZMA_LINK_FLAGS}
${PCRE2_LIBRARIES}
${CURL_LIBRARIES}
${JANSSON_LIBRARIES}
ssl
pthread

View File

@ -35,7 +35,6 @@
#include <maxscale/housekeeper.h>
#include <maxscale/limits.h>
#include <maxscale/log_manager.h>
#include <maxscale/notification.h>
#include <maxscale/pcre2.h>
#include <maxscale/spinlock.h>
#include <maxscale/utils.h>
@ -78,7 +77,6 @@ const char CN_DATA[] = "data";
const char CN_DEFAULT[] = "default";
const char CN_DESCRIPTION[] = "description";
const char CN_ENABLE_ROOT_USER[] = "enable_root_user";
const char CN_FEEDBACK[] = "feedback";
const char CN_FILTERS[] = "filters";
const char CN_FILTER[] = "filter";
const char CN_GATEWAY[] = "gateway";
@ -158,9 +156,7 @@ static char *config_get_value(MXS_CONFIG_PARAMETER *, const char *);
static char *config_get_password(MXS_CONFIG_PARAMETER *);
static const char* config_get_value_string(const MXS_CONFIG_PARAMETER *params, const char *name);
static int handle_global_item(const char *, const char *);
static int handle_feedback_item(const char *, const char *);
static void global_defaults();
static void feedback_defaults();
static bool check_config_objects(CONFIG_CONTEXT *context);
static int maxscale_getline(char** dest, int* size, FILE* file);
static bool check_first_last_char(const char* string, char expected);
@ -171,7 +167,6 @@ static pcre2_code* compile_regex_string(const char* regex_string, bool jit_enabl
int config_get_ifaddr(unsigned char *output);
static int config_get_release_string(char* release);
FEEDBACK_CONF *config_get_feedback_data();
bool config_has_duplicate_sections(const char* config, DUPLICATE_CONTEXT* context);
int create_new_service(CONFIG_CONTEXT *obj);
int create_new_server(CONFIG_CONTEXT *obj);
@ -183,7 +178,6 @@ void config_fix_param(const MXS_MODULE_PARAM *params, MXS_CONFIG_PARAMETER *p);
static const char *config_file = NULL;
static MXS_CONFIG gateway;
static FEEDBACK_CONF feedback;
char *version_string = NULL;
static bool is_persisted_config = false; /**< True if a persisted configuration file is being parsed */
@ -466,10 +460,6 @@ ini_handler(void *userdata, const char *section, const char *name, const char *v
{
return handle_global_item(name, value);
}
else if (strcasecmp(section, CN_FEEDBACK) == 0)
{
return handle_feedback_item(name, value);
}
else if (strlen(section) == 0)
{
MXS_ERROR("Parameter '%s=%s' declared outside a section.", name, value);
@ -837,7 +827,6 @@ config_load(const char *filename)
ss_dassert(!config_file);
global_defaults();
feedback_defaults();
config_file = filename;
bool rval = config_load_and_process(filename, process_config_context);
@ -862,7 +851,6 @@ bool config_reload()
}
global_defaults();
feedback_defaults();
rval = config_load_and_process(config_file, process_config_update);
}
@ -1370,17 +1358,6 @@ config_pollsleep()
return gateway.pollsleep;
}
/**
* Return the feedback config data pointer
*
* @return The feedback config data pointer
*/
FEEDBACK_CONF *
config_get_feedback_data()
{
return &feedback;
}
static struct
{
const char* name;
@ -1798,44 +1775,6 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e
return NULL;
}
/**
* Configuration handler for items in the feedback [feedback] section
*
* @param name The item name
* @param value The item value
* @return 0 on error
*/
static int
handle_feedback_item(const char *name, const char *value)
{
int i;
if (strcmp(name, "feedback_enable") == 0)
{
feedback.feedback_enable = config_truth_value(value);
}
else if (strcmp(name, "feedback_user_info") == 0)
{
feedback.feedback_user_info = MXS_STRDUP_A(value);
}
else if (strcmp(name, "feedback_url") == 0)
{
feedback.feedback_url = MXS_STRDUP_A(value);
}
if (strcmp(name, "feedback_timeout") == 0)
{
feedback.feedback_timeout = atoi(value);
}
if (strcmp(name, "feedback_connect_timeout") == 0)
{
feedback.feedback_connect_timeout = atoi(value);
}
if (strcmp(name, "feedback_frequency") == 0)
{
feedback.feedback_frequency = atoi(value);
}
return 1;
}
/**
* Set the defaults for the global configuration options
*/
@ -1903,24 +1842,6 @@ global_defaults()
gateway.qc_sql_mode = QC_SQL_MODE_DEFAULT;
}
/**
* Set the defaults for the feedback configuration options
*/
static void
feedback_defaults()
{
feedback.feedback_enable = 0;
feedback.feedback_user_info = NULL;
feedback.feedback_last_action = _NOTIFICATION_SEND_PENDING;
feedback.feedback_timeout = _NOTIFICATION_OPERATION_TIMEOUT;
feedback.feedback_connect_timeout = _NOTIFICATION_CONNECT_TIMEOUT;
feedback.feedback_url = NULL;
feedback.feedback_frequency = 1800;
feedback.release_info = gateway.release_string;
feedback.sysname = gateway.sysname;
feedback.mac_sha1 = gateway.mac_sha1;
}
/**
* Process a configuration context update and turn it into the set of object
* we need.
@ -2445,58 +2366,6 @@ config_get_release_string(char* release)
}
}
/**
* Add the 'send_feedback' task to the task list
*/
void
config_enable_feedback_task(void)
{
FEEDBACK_CONF *cfg = config_get_feedback_data();
int url_set = 0;
int user_info_set = 0;
int enable_set = cfg->feedback_enable;
url_set = cfg->feedback_url != NULL && strlen(cfg->feedback_url);
user_info_set = cfg->feedback_user_info != NULL && strlen(cfg->feedback_user_info);
if (enable_set && url_set && user_info_set)
{
/* Add the task to the tasl list */
if (hktask_add("send_feedback", module_feedback_send, cfg, cfg->feedback_frequency))
{
MXS_NOTICE("Notification service feedback task started: URL=%s, User-Info=%s, "
"Frequency %u seconds",
cfg->feedback_url,
cfg->feedback_user_info,
cfg->feedback_frequency);
}
}
else
{
if (enable_set)
{
MXS_ERROR("Notification service feedback cannot start: feedback_enable=1 but"
" some required parameters are not set: %s%s%s",
url_set == 0 ? "feedback_url is not set" : "",
(user_info_set == 0 && url_set == 0) ? ", " : "",
user_info_set == 0 ? "feedback_user_info is not set" : "");
}
else
{
MXS_INFO("Notification service feedback is not enabled.");
}
}
}
/**
* Remove the 'send_feedback' task
*/
void
config_disable_feedback_task(void)
{
hktask_remove("send_feedback");
}
unsigned long config_get_gateway_id()
{
return gateway.id;

View File

@ -12,21 +12,7 @@
*/
/**
* @file load_utils.c Utility functions to aid the loading of dynamic
* modules into the gateway
*
* @verbatim
* Revision History
*
* Date Who Description
* 13/06/13 Mark Riddoch Initial implementation
* 14/06/13 Mark Riddoch Updated to add call to ModuleInit if one is
* defined in the loaded module.
* Also updated to call fixed GetModuleObject
* 02/06/14 Mark Riddoch Addition of module info
* 26/02/15 Massimiliano Pinto Addition of module_feedback_send
*
* @endverbatim
* @file load_utils.c Utility functions for loading of modules
*/
#include "maxscale/modules.h"
@ -37,14 +23,10 @@
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#include <curl/curl.h>
#include <sys/utsname.h>
#include <openssl/sha.h>
#include <maxscale/modinfo.h>
#include <maxscale/log_manager.h>
#include <maxscale/version.h>
#include <maxscale/notification.h>
#include <maxscale/paths.h>
#include <maxscale/alloc.h>
#include <maxscale/json_api.h>
@ -72,45 +54,6 @@ static LOADED_MODULE* register_module(const char *module,
void *dlhandle,
MXS_MODULE *mod_info);
static void unregister_module(const char *module);
int module_create_feedback_report(GWBUF **buffer, LOADED_MODULE *modules, FEEDBACK_CONF *cfg);
int do_http_post(GWBUF *buffer, void *cfg);
struct MemoryStruct
{
char *data;
size_t size;
};
/**
* Callback write routine for curl library, getting remote server reply
*
* @param contents New data to add
* @param size Data size
* @param nmemb Elements in the buffer
* @param userp Pointer to the buffer
* @return 0 on failure, memory size on success
*
*/
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *data = (char*)MXS_REALLOC(mem->data, mem->size + realsize + 1);
if (data == NULL)
{
return 0;
}
mem->data = data;
memcpy(&(mem->data[mem->size]), contents, realsize);
mem->size += realsize;
mem->data[mem->size] = 0;
return realsize;
}
static bool check_module(const MXS_MODULE *mod_info, const char *type, const char *module)
{
@ -548,22 +491,6 @@ json_t* module_list_to_json(const char* host)
return mxs_json_resource(host, MXS_JSON_API_MODULES, arr);
}
void moduleShowFeedbackReport(DCB *dcb)
{
GWBUF *buffer;
LOADED_MODULE *modules_list = registered;
FEEDBACK_CONF *feedback_config = config_get_feedback_data();
if (!module_create_feedback_report(&buffer, modules_list, feedback_config))
{
MXS_ERROR("Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory");
return;
}
dcb_printf(dcb, "%s", (char *)GWBUF_DATA(buffer));
gwbuf_free(buffer);
}
/**
* Provide a row to the result set that defines the set of modules
*
@ -638,354 +565,6 @@ RESULTSET *moduleGetList()
return set;
}
void module_feedback_send(void* data)
{
LOADED_MODULE *modules_list = registered;
CURL *curl = NULL;
CURLcode res;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
GWBUF *buffer = NULL;
void *data_ptr = NULL;
long http_code = 0;
int last_action = _NOTIFICATION_SEND_PENDING;
time_t now;
struct tm *now_tm;
int hour;
int n_mod = 0;
char hex_setup_info[2 * SHA_DIGEST_LENGTH + 1] = "";
int http_send = 0;
now = time(NULL);
struct tm now_result;
now_tm = localtime_r(&now, &now_result);
hour = now_tm->tm_hour;
FEEDBACK_CONF *feedback_config = (FEEDBACK_CONF *) data;
/* Configuration check */
if (feedback_config->feedback_enable == 0 ||
feedback_config->feedback_url == NULL ||
feedback_config->feedback_user_info == NULL)
{
MXS_ERROR("Error in module_feedback_send(): some mandatory parameters are not set"
" feedback_enable=%u, feedback_url=%s, feedback_user_info=%s",
feedback_config->feedback_enable,
feedback_config->feedback_url == NULL ? "NULL" : feedback_config->feedback_url,
feedback_config->feedback_user_info == NULL ?
"NULL" : feedback_config->feedback_user_info);
feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR;
return;
}
/**
* Task runs nightly, from 2 AM to 4 AM
*
* If it's done in that time interval, it will be skipped
*/
if (hour > 4 || hour < 2)
{
/* It's not the rigt time, mark it as to be done and return */
feedback_config->feedback_last_action = _NOTIFICATION_SEND_PENDING;
MXS_INFO("module_feedback_send(): execution skipped, current hour [%d]"
" is not within the proper interval (from 2 AM to 4 AM)",
hour);
return;
}
/* Time to run the task: if a previous run was succesfull skip next runs */
if (feedback_config->feedback_last_action == _NOTIFICATION_SEND_OK)
{
/* task was done before, return */
MXS_INFO("module_feedback_send(): execution skipped because of previous "
"succesful run: hour is [%d], last_action [%d]",
hour, feedback_config->feedback_last_action);
return;
}
MXS_INFO("module_feedback_send(): task now runs: hour is [%d], last_action [%d]",
hour, feedback_config->feedback_last_action);
if (!module_create_feedback_report(&buffer, modules_list, feedback_config))
{
MXS_ERROR("Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory");
feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR;
return;
}
/* try sending data via http/https post */
http_send = do_http_post(buffer, feedback_config);
if (http_send == 0)
{
feedback_config->feedback_last_action = _NOTIFICATION_SEND_OK;
}
else
{
feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR;
MXS_INFO("Error in module_create_feedback_report(): do_http_post ret_code is %d", http_send);
}
MXS_INFO("module_feedback_send(): task completed: hour is [%d], last_action [%d]",
hour,
feedback_config->feedback_last_action);
gwbuf_free(buffer);
}
/**
* Create the feedback report as string.
* I t could be sent to notification service
* or just printed via maxadmin/telnet
*
* @param buffe The pointr for GWBUF allocation, to be freed by the caller
* @param modules The mouleds list
* @param cfg The feedback configuration
* @return 0 on failure, 1 on success
*
*/
int
module_create_feedback_report(GWBUF **buffer, LOADED_MODULE *modules, FEEDBACK_CONF *cfg)
{
LOADED_MODULE *ptr = modules;
int n_mod = 0;
char *data_ptr = NULL;
char hex_setup_info[2 * SHA_DIGEST_LENGTH + 1] = "";
time_t now;
struct tm *now_tm;
int report_max_bytes = 0;
if (buffer == NULL)
{
return 0;
}
now = time(NULL);
/* count loaded modules */
while (ptr)
{
ptr = ptr->next;
n_mod++;
}
/* module lists pointer is set back to the head */
ptr = modules;
/**
* allocate gwbuf for data to send
*
* each module gives 4 rows
* product and release rows add 7 rows
* row is _NOTIFICATION_REPORT_ROW_LEN bytes long
*/
report_max_bytes = ((n_mod * 4) + 7) * (_NOTIFICATION_REPORT_ROW_LEN + 1);
*buffer = gwbuf_alloc(report_max_bytes);
if (*buffer == NULL)
{
return 0;
}
/* encode MAC-sha1 to HEX */
gw_bin2hex(hex_setup_info, cfg->mac_sha1, SHA_DIGEST_LENGTH);
data_ptr = (char *)GWBUF_DATA(*buffer);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "FEEDBACK_SERVER_UID\t%s\n", hex_setup_info);
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "FEEDBACK_USER_INFO\t%s\n",
cfg->feedback_user_info == NULL ? "not_set" : cfg->feedback_user_info);
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "VERSION\t%s\n", MAXSCALE_VERSION);
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN * 2, "NOW\t%lu\nPRODUCT\t%s\n", now, "maxscale");
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "Uname_sysname\t%s\n", cfg->sysname);
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "Uname_distribution\t%s\n", cfg->release_info);
data_ptr += strlen(data_ptr);
while (ptr)
{
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN * 2,
"module_%s_type\t%s\nmodule_%s_version\t%s\n",
ptr->module, ptr->type, ptr->module, ptr->version);
data_ptr += strlen(data_ptr);
if (ptr->info)
{
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "module_%s_api\t%d.%d.%d\n",
ptr->module,
ptr->info->api_version.major,
ptr->info->api_version.minor,
ptr->info->api_version.patch);
data_ptr += strlen(data_ptr);
snprintf(data_ptr, _NOTIFICATION_REPORT_ROW_LEN, "module_%s_releasestatus\t%s\n",
ptr->module,
ptr->info->status == MXS_MODULE_IN_DEVELOPMENT
? "In Development"
: (ptr->info->status == MXS_MODULE_ALPHA_RELEASE
? "Alpha"
: (ptr->info->status == MXS_MODULE_BETA_RELEASE
? "Beta"
: (ptr->info->status == MXS_MODULE_GA
? "GA"
: (ptr->info->status == MXS_MODULE_EXPERIMENTAL
? "Experimental" : "Unknown")))));
data_ptr += strlen(data_ptr);
}
ptr = ptr->next;
}
return 1;
}
/**
* Send data to notification service via http/https
*
* @param buffer The GWBUF with data to send
* @param cfg The configuration details of notification service
* @return 0 on success, != 0 on failure
*/
int
do_http_post(GWBUF *buffer, void *cfg)
{
CURL *curl = NULL;
CURLcode res;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
long http_code = 0;
struct MemoryStruct chunk;
int ret_code = 1;
FEEDBACK_CONF *feedback_config = (FEEDBACK_CONF *) cfg;
/* allocate first memory chunck for httpd servr reply */
chunk.data = (char*)MXS_MALLOC(1); /* will be grown as needed by the realloc above */
MXS_ABORT_IF_NULL(chunk.data);
chunk.size = 0; /* no data at this point */
/* Initializing curl library for data send via HTTP */
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl)
{
char error_message[CURL_ERROR_SIZE] = "";
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_message);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, feedback_config->feedback_connect_timeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, feedback_config->feedback_timeout);
/* curl API call for data send via HTTP POST using a "file" type input */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "data",
CURLFORM_BUFFER, "report.txt",
CURLFORM_BUFFERPTR, (char *)GWBUF_DATA(buffer),
CURLFORM_BUFFERLENGTH, strlen((char *)GWBUF_DATA(buffer)),
CURLFORM_CONTENTTYPE, "text/plain",
CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
/* some servers don't like requests that are made without a user-agent field, so we provide one */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "MaxScale-agent/http-1.0");
/* Force HTTP/1.0 */
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt(curl, CURLOPT_URL, feedback_config->feedback_url);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
{
ret_code = 2;
MXS_ERROR("do_http_post(), curl call for [%s] failed due: %s, %s",
feedback_config->feedback_url,
curl_easy_strerror(res),
error_message);
goto cleanup;
}
else
{
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
}
if (http_code == 302)
{
char *from = strstr(chunk.data, "<h1>ok</h1>");
if (from)
{
ret_code = 0;
}
else
{
ret_code = 3;
goto cleanup;
}
}
else
{
MXS_ERROR("do_http_post(), Bad HTTP Code from remote server: %lu", http_code);
ret_code = 4;
goto cleanup;
}
}
else
{
MXS_ERROR("do_http_post(), curl object not initialized");
ret_code = 1;
goto cleanup;
}
MXS_INFO("do_http_post() ret_code [%d], HTTP code [%ld]",
ret_code, http_code);
cleanup:
if (chunk.data)
{
MXS_FREE(chunk.data);
}
if (curl)
{
curl_easy_cleanup(curl);
curl_formfree(formpost);
}
curl_global_cleanup();
return ret_code;
}
const MXS_MODULE *get_module(const char *name, const char *type)
{
LOADED_MODULE *mod = find_module(name);

View File

@ -14,21 +14,6 @@
/**
* @file modules.h Utilities for loading modules
*
* The module interface used within the gateway
*
* @verbatim
* Revision History
*
* Date Who Description
* 13/06/13 Mark Riddoch Initial implementation
* 08/07/13 Mark Riddoch Addition of monitor modules
* 29/05/14 Mark Riddoch Addition of filter modules
* 01/10/14 Mark Riddoch Addition of call to unload all modules on shutdown
* 19/02/15 Mark Riddoch Addition of moduleGetList
* 26/02/15 Massimiliano Pinto Addition of module_feedback_send
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
@ -107,20 +92,6 @@ void dprintAllModules(DCB *);
*/
RESULTSET *moduleGetList();
/**
* @brief Send loaded modules info to notification service
*
* @param data The configuration details of notification service
*/
void module_feedback_send(void*);
/**
* @brief Show feedback report
*
* Prints the feedback report to a DCB
*/
void moduleShowFeedbackReport(DCB *dcb);
typedef struct mxs_module_iterator
{
const char* type;

View File

@ -596,8 +596,6 @@ int service_launch_all()
int n = 0, i;
bool error = false;
config_enable_feedback_task();
ptr = allServices;
while (ptr && !ptr->svc_do_shutdown)
{

View File

@ -18,7 +18,6 @@ add_executable(test_spinlock testspinlock.cc)
add_executable(test_trxcompare testtrxcompare.cc ../../../query_classifier/test/testreader.cc)
add_executable(test_trxtracking testtrxtracking.cc)
add_executable(test_users testusers.cc)
add_executable(testfeedback testfeedback.cc)
add_executable(testmaxscalepcre2 testmaxscalepcre2.cc)
add_executable(testmodulecmd testmodulecmd.cc)
add_executable(testconfig testconfig.cc)
@ -45,7 +44,6 @@ target_link_libraries(test_spinlock maxscale-common)
target_link_libraries(test_trxcompare maxscale-common)
target_link_libraries(test_trxtracking maxscale-common)
target_link_libraries(test_users maxscale-common)
target_link_libraries(testfeedback maxscale-common)
target_link_libraries(testmaxscalepcre2 maxscale-common)
target_link_libraries(testmodulecmd maxscale-common)
target_link_libraries(testconfig maxscale-common)
@ -86,11 +84,4 @@ add_test(TestTrxCompare_MaxScale test_trxcompare ${CMAKE_CURRENT_SOURCE_DIR}/../
add_test(TestJson testjson)
add_test(TestHttp testhttp)
# This test requires external dependencies and thus cannot be run
# as a part of the core test set
if(TEST_FEEDBACK)
add_test(TestFeedback testfeedback)
set_tests_properties(TestFeedback PROPERTIES TIMEOUT 30)
endif()
add_subdirectory(rest-api)

View File

@ -1,120 +0,0 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
*
* @verbatim
* Revision History
*
* Date Who Description
* 09-03-2015 Markus Mäkelä Initial implementation
* 10-03-2015 Massimiliano Pinto Added http_check
*
* @endverbatim
*/
// To ensure that ss_info_assert asserts also when builing in non-debug mode.
#if !defined(SS_DEBUG)
#define SS_DEBUG
#endif
#if defined(NDEBUG)
#undef NDEBUG
#endif
#define FAILTEST(s) printf("TEST FAILED: " s "\n");return 1;
#include <mysql.h>
#include <stdio.h>
#include <maxscale/notification.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <maxscale/alloc.h>
#include <maxscale/housekeeper.h>
#include <maxscale/buffer.h>
#include <regex.h>
#include <maxscale/maxscale_test.h>
#include "../maxscale/config.h"
#include "../load_utils.cc"
static const char* server_options[] =
{
"MariaDB Corporation MaxScale",
"--no-defaults",
"--datadir=.",
"--language=.",
"--skip-innodb",
"--default-storage-engine=myisam",
NULL
};
const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
static const char* server_groups[] =
{
"embedded",
"server",
"server",
"embedded",
"server",
"server",
NULL
};
int main(int argc, char** argv)
{
FEEDBACK_CONF* fc;
GWBUF* buf;
regex_t re;
char* home;
char* cnf;
hkinit();
cnf = (char*)MXS_MALLOC(sizeof(char) * (strlen(TEST_DIR) + strlen("/maxscale.cnf") + 1));
MXS_ABORT_IF_NULL(cnf);
sprintf(cnf, "%s/maxscale.cnf", TEST_DIR);
printf("Config: %s\n", cnf);
if (mysql_library_init(num_elements, (char**)server_options, (char**)server_groups))
{
FAILTEST("Failed to initialize embedded library.");
}
config_load(cnf);
config_enable_feedback_task();
if ((fc = config_get_feedback_data()) == NULL)
{
FAILTEST("Configuration for Feedback was NULL.");
}
regcomp(&re, fc->feedback_user_info, 0);
module_create_feedback_report(&buf, NULL, fc);
if (regexec(&re, (char*)buf->start, 0, NULL, 0))
{
FAILTEST("Regex match of 'user_info' failed.");
}
if (do_http_post(buf, fc) != 0)
{
FAILTEST("Http send failed\n");
}
mysql_library_end();
return 0;
}

View File

@ -24,27 +24,6 @@
*
* There are two "built in" commands, the help command and the quit
* command.
*
* @verbatim
* Revision History
*
* Date Who Description
* 20/06/13 Mark Riddoch Initial implementation
* 17/07/13 Mark Riddoch Additional commands
* 09/08/13 Massimiliano Pinto Added enable/disable commands (now only for log)
* 20/05/14 Mark Riddoch Added ability to give server and service names rather
* than simply addresses
* 23/05/14 Mark Riddoch Added support for developer and user modes
* 29/05/14 Mark Riddoch Add Filter support
* 16/10/14 Mark Riddoch Add show eventq
* 05/03/15 Massimiliano Pinto Added enable/disable feedback
* 27/05/15 Martin Brampton Add show persistent [server]
* 06/11/15 Martin Brampton Add show buffers (conditional compilation)
* 23/05/16 Massimiliano Pinto 'add user' and 'remove user'
* no longer accept password parameter
* 27/06/16 Martin Brampton Modify to work with list manager sessions
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
@ -170,12 +149,6 @@ struct subcommand showoptions[] =
"Usage: show eventstats",
{0}
},
{
"feedbackreport", 0, 0, moduleShowFeedbackReport,
"Show the report of MaxScale loaded modules, suitable for Notification Service",
"Usage: show feedbackreport",
{0}
},
{
"filter", 1, 1, dprintFilter,
"Show filter details",
@ -723,8 +696,6 @@ static void enable_sess_log_priority(DCB *dcb, char *arg1, char *arg2);
static void disable_sess_log_priority(DCB *dcb, char *arg1, char *arg2);
static void enable_service_root(DCB *dcb, SERVICE *service);
static void disable_service_root(DCB *dcb, SERVICE *service);
static void enable_feedback_action();
static void disable_feedback_action();
static void enable_syslog();
static void disable_syslog();
static void enable_maxlog();
@ -771,14 +742,6 @@ struct subcommand enableoptions[] =
"Example: enable root my-service",
{ARG_TYPE_SERVICE}
},
{
"feedback",
0, 0,
enable_feedback_action,
"Enable MaxScale feedback to notification service",
"Usage: enable feedback",
{0}
},
{
"syslog",
0, 0,
@ -854,14 +817,6 @@ struct subcommand disableoptions[] =
"Example: disable root my-service",
{ARG_TYPE_SERVICE}
},
{
"feedback",
0, 0,
disable_feedback_action,
"Disable MaxScale feedback to notification service",
"Usage: disable feedback",
{0}
},
{
"syslog",
0, 0,
@ -2550,29 +2505,6 @@ set_log_throttling(DCB *dcb, int count, int window_ms, int suppress_ms)
}
}
/**
* Re-enable sendig MaxScale module list via http
* Proper [feedback] section in MaxSclale.cnf
* is required.
*/
static void
enable_feedback_action(void)
{
config_enable_feedback_task();
return;
}
/**
* Disable sendig MaxScale module list via http
*/
static void
disable_feedback_action(void)
{
config_disable_feedback_task();
return;
}
/**
* Enable syslog logging.
*/