Skip to content

Commit

Permalink
event scope class
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-f committed Feb 1, 2017
1 parent 9e44c75 commit e340987
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 58 deletions.
14 changes: 5 additions & 9 deletions userspace/libsinsp/docker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,10 @@ void docker::handle_event(Json::Value&& root)
{
image = img.asString();
}
std::string scope;
event_scope scope;
if(m_machine_id.length())
{
event_scope::assemble(scope, "host.mac", m_machine_id);
}
else
{
scope.clear();
scope.add("host.mac", m_machine_id);
}
if(is_image_event(event_name))
{
Expand All @@ -359,11 +355,11 @@ void docker::handle_event(Json::Value&& root)
}
if(!id.empty())
{
event_scope::assemble(scope, "container.image", id);
scope.add("container.image", id);
}
else if(!image.empty())
{
event_scope::assemble(scope, "container.image", image);
scope.add("container.image", image);
}
else
{
Expand All @@ -375,7 +371,7 @@ void docker::handle_event(Json::Value&& root)
{
if(id.length() >= 12)
{
event_scope::assemble(scope, "container.id", id.substr(0, 12));
scope.add("container.id", id.substr(0, 12));
}
}
if(status.length())
Expand Down
18 changes: 9 additions & 9 deletions userspace/libsinsp/k8s_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ bool k8s_event_t::update(const Json::Value& item, k8s_state_t& state)
std::string event_name;
std::string description;
severity_t severity = sinsp_logger::SEV_EVT_INFORMATION;
std::string scope;
event_scope scope;
tag_map_t tags;

const Json::Value& obj = item["involvedObject"];
Expand Down Expand Up @@ -878,17 +878,17 @@ bool k8s_event_t::update(const Json::Value& item, k8s_state_t& state)
const std::string& node_name = comp->get_node_name();
if(!node_name.empty())
{
event_scope::assemble(scope, "kubernetes.node.name", node_name);
scope.add("kubernetes.node.name", node_name);
}
const std::string& ns = comp->get_namespace();
if(!ns.empty())
{
event_scope::assemble(scope, "kubernetes.namespace.name", ns);
scope.add("kubernetes.namespace.name", ns);
}
const std::string& comp_name = comp->get_name();
if(comp_name.empty())
{
event_scope::assemble(scope, std::string("kubernetes.").append(t).append(".name"), comp_name);
scope.add(std::string("kubernetes.").append(t).append(".name"), comp_name);
}
/* no labels for now
for(const auto& label : comp->get_labels())
Expand Down Expand Up @@ -930,22 +930,22 @@ bool k8s_event_t::update(const Json::Value& item, k8s_state_t& state)

tags["source"] = "kubernetes";
g_logger.log(sinsp_user_event::to_string(epoch_time_evt_s, std::move(event_name), std::move(description),
std::move(scope), std::move(tags)), severity);
std::move(scope), std::move(tags)), severity);

// TODO: sysdig capture?
#endif // _WIN32

return true;
}

void k8s_event_t::make_scope_impl(const Json::Value& obj, std::string comp, std::string& scope, bool ns)
void k8s_event_t::make_scope_impl(const Json::Value& obj, std::string comp, event_scope& scope, bool ns)
{
if(ns)
{
const std::string& ns_name = get_json_string(obj, "namespace");
if(!ns_name.empty())
{
event_scope::assemble(scope, "kubernetes.namespace.name", ns_name);
scope.add("kubernetes.namespace.name", ns_name);
}
}
if(comp.length() && ci_compare::is_equal(get_json_string(obj, "kind"), comp))
Expand All @@ -954,7 +954,7 @@ void k8s_event_t::make_scope_impl(const Json::Value& obj, std::string comp, std:
if(!comp_name.empty())
{
comp[0] = tolower(comp[0]);
event_scope::assemble(scope, std::string("kubernetes.").append(comp).append(".name"), comp_name);
scope.add(std::string("kubernetes.").append(comp).append(".name"), comp_name);
}
if(comp_name.empty())
{
Expand All @@ -967,7 +967,7 @@ void k8s_event_t::make_scope_impl(const Json::Value& obj, std::string comp, std:
}
}

void k8s_event_t::make_scope(const Json::Value& obj, std::string& scope)
void k8s_event_t::make_scope(const Json::Value& obj, event_scope& scope)
{
if(ci_compare::is_equal(get_json_string(obj, "kind"), "Pod"))
{
Expand Down
5 changes: 3 additions & 2 deletions userspace/libsinsp/k8s_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ class k8s_deployment_t : public k8s_component
//

class k8s_state_t;
class event_scope;

class k8s_event_t : public k8s_component
{
Expand All @@ -522,8 +523,8 @@ class k8s_event_t : public k8s_component
typedef sinsp_logger::event_severity severity_t;
typedef std::unordered_map<std::string, std::string> name_translation_map_t;

void make_scope(const Json::Value& obj, std::string& scope);
void make_scope_impl(const Json::Value& obj, std::string comp, std::string& scope, bool ns = true);
void make_scope(const Json::Value& obj, event_scope& scope);
void make_scope_impl(const Json::Value& obj, std::string comp, event_scope& scope, bool ns = true);

name_translation_map_t m_name_translation;
std::map<std::string, Json::Value> m_postponed_events;
Expand Down
97 changes: 69 additions & 28 deletions userspace/libsinsp/user_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,81 @@ along with sysdig. If not, see <http://www.gnu.org/licenses/>.
#include "sinsp_int.h"
#include "user_event.h"

//
// event_scope
//

const std::string event_scope::SCOPE_OP_AND = "and";

// these string lists contain reserved strings; some of the reserved
// strings are escaped and mandatory to be first in RESERVED_STRINGS
// and have their escaped counterparts in the REPLACEMENT_STRINGS,
// in the same order as they appear in RESERVED_STRINGS
const event_scope::string_list_t event_scope::RESERVED_STRINGS =
{"'"/*!must be first!*/, "=", " and "};
{"'"/*!must be first!*/, "=", " and ", " "};
const event_scope::string_list_t event_scope::REPLACEMENT_STRINGS =
{"\\'", "='", "' and "}; // !do not change order!
{"\\'"/*!must be first!*/};

event_scope::event_scope(const std::string& key, const std::string& value)
{
add(key, value, "");
}

bool event_scope::add(const std::string& key, const std::string& value, const std::string& op)
{
if(check(key))
{
std::string k(key);
std::string o(!m_scope.empty() ? op : "");
std::string v(value);
replace(v);
if(!v.empty())
{
if(!o.empty())
{
m_scope.append(1, ' ').append(trim(o)).append(1, ' ');
}
m_scope.append(trim(k)).append("='").append(trim(v)).append(1, 0x27);
return true;
}
}
else
{
g_logger.log("Scope key has invalid value: [" + key + "], not added to scope.", sinsp_logger::SEV_WARNING);
}
return false;
}

string&& event_scope::escape(std::string&& scope)
string& event_scope::replace(std::string& value)
{
trim(scope);
string_list_t::const_iterator res_it = RESERVED_STRINGS.cbegin();
string_list_t::const_iterator res_end = RESERVED_STRINGS.cend();
string_list_t::const_iterator rep_it = REPLACEMENT_STRINGS.cbegin();
string_list_t::const_iterator rep_end = REPLACEMENT_STRINGS.cend();
for(; res_it != res_end && rep_it != rep_end; ++res_it, ++rep_it)
ASSERT(RESERVED_STRINGS.size() >= REPLACEMENT_STRINGS.size());

if(check(value))
{
trim(value);
string_list_t::const_iterator res_it = RESERVED_STRINGS.cbegin();
string_list_t::const_iterator res_end = RESERVED_STRINGS.cend();
string_list_t::const_iterator rep_it = REPLACEMENT_STRINGS.cbegin();
string_list_t::const_iterator rep_end = REPLACEMENT_STRINGS.cend();
for(; res_it != res_end && rep_it != rep_end; ++res_it)
{
replace_in_place(value, *res_it, *rep_it);
if(++rep_it == rep_end) { break; }
}
}
else
{
replace_in_place(scope, *res_it, *rep_it);
g_logger.log("Cannot replace invalid value: [" + value + "], string will be cleared.", sinsp_logger::SEV_WARNING);
value.clear();
}
scope.append(1, 0x27); // terminating single quote
return std::move(scope);
return value;
}

// utility function to check that scope entry is valid;
// valid entries can not contain '=' character or " and " string
bool event_scope::check(const std::string& scope)
{
if(scope.empty()) { return true; }
string_list_t::const_iterator rs = RESERVED_STRINGS.cbegin();
++rs;
for(; rs != RESERVED_STRINGS.end(); ++rs)
Expand All @@ -56,21 +107,10 @@ bool event_scope::check(const std::string& scope)
return true;
}

bool event_scope::assemble(std::string& scope, const std::string& name, const std::string& value)
{
if(check(name) && check(value))
{
if(scope.length()) { scope.append(" and "); }
scope.append(name).append(1, '=').append(value);
return true;
}
else
{
g_logger.log("Invalid scope entry for " + name + ": [" + value + ']', sinsp_logger::SEV_WARNING);
}
return false;
}

//
// user_event_meta_t
//
const std::string user_event_meta_t::PERMIT_ALL = "all";

user_event_meta_t::user_event_meta_t(const std::string& kind, const type_list_t& types):
Expand Down Expand Up @@ -317,18 +357,19 @@ sinsp_user_event& sinsp_user_event::operator=(sinsp_user_event&& other)
std::string sinsp_user_event::to_string(uint64_t timestamp,
std::string&& name,
std::string&& description,
std::string&& scope,
event_scope&& scope,
tag_map_t&& tags,
uint32_t sev)
{
const std::string from("\"");
const std::string to("\\\"");

std::string s(scope.get());
std::ostringstream ostr;
ostr << "timestamp: " << timestamp << '\n' <<
"name: \"" << replace_in_place(name, from, to) << "\"\n"
"description: \"" << replace_in_place(description, from, to) << "\"\n"
"scope: \"" << replace_in_place(scope, from, to) << "\"\n";
"scope: \"" << replace_in_place(s, from, to) << "\"\n";

if(sev != UNKNOWN_SEVERITY)
{
Expand Down
40 changes: 30 additions & 10 deletions userspace/libsinsp/user_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,47 @@ along with sysdig. If not, see <http://www.gnu.org/licenses/>.
//
// scope utilities
//
struct event_scope
class event_scope
{
public:
typedef std::vector<std::string> string_list_t;

static const std::string SCOPE_OP_AND;
static const string_list_t RESERVED_STRINGS;
static const string_list_t REPLACEMENT_STRINGS;

// utility function to escape scope entries and wrap them in single quotes;
// this function is used internally but is left public for testing purposes
static string&& escape(std::string&& scope);
event_scope(const std::string& key = "", const std::string& value = "");

bool add(const std::string& key, const std::string& value, const std::string& op = SCOPE_OP_AND);

std::string get();

void clear();

// utility function to check that scope entry is valid;
// valid entries can not contain '=' character or " and " string
// valid entries can not contain characters from RESERVED_STRINGS
// which are not present in REPLACEMENT_STRINGS
static bool check(const std::string& scope);

// utility function to check that scope entry is valid and
// assemble it; returns true if succesful, false otherwise;
// valid entries can not contain '=' character or " and " string
static bool assemble(std::string& scope, const std::string& name, const std::string& value);
private:

// utility function to replace RESERVED_STRINGS with their
// counterparts in REPLACEMENT_STRINGS
static string& replace(std::string& scope);

std::string m_scope;
};

inline std::string event_scope::get()
{
return m_scope;
}

inline void event_scope::clear()
{
m_scope.clear();
}


//
// user-configured event meta
Expand Down Expand Up @@ -232,7 +252,7 @@ class sinsp_user_event
static std::string to_string(uint64_t timestamp,
std::string&& name,
std::string&& description,
std::string&& scope,
event_scope&& scope,
tag_map_t&& tags,
uint32_t sev = UNKNOWN_SEVERITY);

Expand Down

0 comments on commit e340987

Please sign in to comment.