MXS-591 Add filter for injecting comments

Comments specified in the cnf file will be injected as a comment before
every sql statement.
This commit is contained in:
Marko
2018-06-12 15:21:35 +03:00
parent 69b19d1473
commit de1f95028b
7 changed files with 347 additions and 0 deletions

View File

@ -16,3 +16,4 @@ add_subdirectory(tee)
add_subdirectory(throttlefilter)
add_subdirectory(topfilter)
add_subdirectory(tpmfilter)
add_subdirectory(comment)

View File

@ -0,0 +1,4 @@
add_library(comment SHARED commentfilter.cc commentfiltersession.cc)
set_target_properties(comment PROPERTIES VERSION "1.0.0")
install_module(comment core)

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
// All log messages from this module are prefixed with this
#define MXS_MODULE_NAME "commentfilter"
#include "commentfilter.hh"
#include <string>
#include <cstring>
namespace
{
const char CN_INJECT[] = "inject";
}
// This declares a module in MaxScale
extern "C" MXS_MODULE* MXS_CREATE_MODULE()
{
static MXS_MODULE info =
{
MXS_MODULE_API_FILTER,
MXS_MODULE_IN_DEVELOPMENT,
MXS_FILTER_VERSION,
"A comment filter that can inject comments in sql queries",
"V1.0.0",
RCAP_TYPE_NONE,
&CommentFilter::s_object, // This is defined in the MaxScale filter template
NULL, /* Process init. */
NULL, /* Process finish. */
NULL, /* Thread init. */
NULL, /* Thread finish. */
{
{ CN_INJECT, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED },
{ MXS_END_MODULE_PARAMS }
}
};
return &info;
}
CommentFilter::CommentFilter(std::string comment) : m_comment(comment)
{
MXS_INFO("Comment filter with comment [%s] created.", m_comment.c_str());
}
CommentFilter::~CommentFilter()
{
}
// static
CommentFilter* CommentFilter::create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* pParams)
{
return new CommentFilter(config_get_string(pParams, CN_INJECT));
}
CommentFilterSession* CommentFilter::newSession(MXS_SESSION* pSession)
{
return CommentFilterSession::create(pSession, this);
}
// static
void CommentFilter::diagnostics(DCB* pDcb) const
{
dcb_printf(pDcb, "Comment filter with comment: %s", m_comment.c_str());
}
// static
json_t* CommentFilter::diagnostics_json() const
{
json_t* rval = json_object();
json_object_set_new(rval, "Comment", json_string(m_comment.c_str()));
return rval;
}
// static
uint64_t CommentFilter::getCapabilities()
{
return RCAP_TYPE_NONE;
}

View File

@ -0,0 +1,53 @@
#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.
*/
#include <maxscale/cppdefs.hh>
#include <maxscale/filter.hh>
#include "commentfiltersession.hh"
#include <string>
class CommentFilter : public maxscale::Filter<CommentFilter, CommentFilterSession>
{
public:
// Prevent copy-constructor and assignment operator usage
CommentFilter(const CommentFilter&) = delete;
CommentFilter& operator = (const CommentFilter&) = delete;
~CommentFilter();
// Creates a new filter instance
static CommentFilter* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* ppParams);
// Creates a new session for this filter
CommentFilterSession* newSession(MXS_SESSION* pSession);
// Print diagnostics to a DCB
void diagnostics(DCB* pDcb) const;
// Returns JSON form diagnostic data
json_t* diagnostics_json() const;
// Get filter capabilities
uint64_t getCapabilities();
std::string comment() const
{
return m_comment;
}
private:
std::string m_comment;
// Used in the create function
CommentFilter(std::string comment);
};

View File

@ -0,0 +1,80 @@
/*
* 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.
*/
// All log messages from this module are prefixed with this
#define MXS_MODULE_NAME "commentfilter"
#include "commentfiltersession.hh"
#include "commentfilter.hh"
#include <maxscale/modutil.hh>
#include <string>
#include <regex>
using namespace std;
CommentFilterSession::CommentFilterSession(MXS_SESSION* pSession, const CommentFilter* pFilter)
: maxscale::FilterSession(pSession),
m_filter(*pFilter)
{
}
CommentFilterSession::~CommentFilterSession()
{
}
//static
CommentFilterSession* CommentFilterSession::create(MXS_SESSION* pSession, const CommentFilter* pFilter)
{
return new CommentFilterSession(pSession, pFilter);
}
void CommentFilterSession::close()
{
}
int CommentFilterSession::routeQuery(GWBUF* pPacket)
{
if (modutil_is_SQL(pPacket))
{
string sql = mxs::extract_sql(pPacket);
string comment = parseComment(m_filter.comment());
string newsql = string("/* ").append(comment).append(" */").append(sql);
pPacket = modutil_replace_SQL(pPacket, (char*)newsql.c_str());
//maxscale expects contiguous memory to arrive from client so we must make the buffer contiguous
//after using modutil_replace_SQL.
GWBUF* pModified_packet = gwbuf_make_contiguous(pPacket);
if (pModified_packet)
{
pPacket = pModified_packet;
}
else
{
gwbuf_free(pPacket);
pPacket = NULL;
}
}
return pPacket ? mxs::FilterSession::routeQuery(pPacket) : 1;
}
int CommentFilterSession::clientReply(GWBUF* pPacket)
{
return mxs::FilterSession::clientReply(pPacket);
}
//TODO this probably should be refactored in some way in case we add more variables
string CommentFilterSession::parseComment(string comment)
{
string ip = m_pSession->client_dcb->remote;
string parsedComment = std::regex_replace(comment, std::regex("\\$IP"), ip);
return parsedComment;
}

View File

@ -0,0 +1,48 @@
#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.
*/
#include <maxscale/cppdefs.hh>
#include <maxscale/filter.hh>
#include <string>
class CommentFilter;
class CommentFilterSession : public maxscale::FilterSession
{
// Prevent copy-constructor and assignment operator usage
CommentFilterSession(const CommentFilterSession&);
CommentFilterSession& operator = (const CommentFilterSession&);
public:
~CommentFilterSession();
// Called when a client session has been closed
void close();
// Create a new filter session
static CommentFilterSession* create(MXS_SESSION* pSession, const CommentFilter* pFilter);
// Handle a query from the client
int routeQuery(GWBUF* pPacket);
// Handle a reply from server
int clientReply(GWBUF* pPacket);
private:
// Used in the create function
CommentFilterSession(MXS_SESSION* pSession, const CommentFilter* pFilter);
const CommentFilter& m_filter;
std::string parseComment(std::string comment);
};