diff --git a/include/SecurityGroup.h b/include/SecurityGroup.h index 887ec5e099..d94f6342d0 100644 --- a/include/SecurityGroup.h +++ b/include/SecurityGroup.h @@ -179,7 +179,14 @@ private: * @param error describing the problem if any * @return true if the rule is valid */ - bool isValidRule(const VectorAttribute * rule, std::string& error) const; + bool is_valid(const VectorAttribute * rule, std::string& error) const; + + /** + * Remove duplicit rules. The duplicits are removed from obj_template + * not from passed parameter + * @param rules as vector of VectorAttributes + */ + void remove_duplicates(std::vector& rules); /** * Checks the new rules diff --git a/src/secgroup/SecurityGroup.cc b/src/secgroup/SecurityGroup.cc index 29566c109d..dd5d9854e7 100644 --- a/src/secgroup/SecurityGroup.cc +++ b/src/secgroup/SecurityGroup.cc @@ -57,7 +57,7 @@ SecurityGroup::SecurityGroup( int SecurityGroup::insert(SqlDB *db, string& error_str) { - vector rules; + vector rules; erase_template_attribute("NAME",name); @@ -70,12 +70,14 @@ int SecurityGroup::insert(SqlDB *db, string& error_str) for ( auto rule : rules ) { - if (!isValidRule(rule, error_str)) + if (!is_valid(rule, error_str)) { goto error_valid; } } + remove_duplicates(rules); + if ( insert_replace(db, false, error_str) != 0 ) { goto error_db; @@ -299,7 +301,7 @@ void SecurityGroup::get_rules(vector& result) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool SecurityGroup::isValidRule(const VectorAttribute * rule, string& error) const +bool SecurityGroup::is_valid(const VectorAttribute * rule, string& error) const { string value, ip, proto; @@ -431,20 +433,59 @@ bool SecurityGroup::isValidRule(const VectorAttribute * rule, string& error) con /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void SecurityGroup::remove_duplicates(vector& rules) +{ + for (auto rule : rules) + { + rule->replace("HASH", one_util::sha1_digest(rule->marshall())); + } + + // Sort to get duplicates next to each other + sort(rules.begin(), rules.end(), + [](const VectorAttribute* va1, const VectorAttribute* va2) { + return va1->vector_value("HASH") < va2->vector_value("HASH"); + }); + + string prev_value; + + for (auto rule : rules) + { + string value = rule->vector_value("HASH"); + + if (value == prev_value) + { + auto r = obj_template->remove(rule); + + delete r; + } + else + { + rule->remove("HASH"); + } + + prev_value = move(value); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int SecurityGroup::post_update_template(string& error) { - vector rules; + vector rules; - get_template_attribute("RULE", rules); + obj_template->get("RULE", rules); for ( auto rule : rules ) { - if (!isValidRule(rule, error)) + if (!is_valid(rule, error)) { return -1; } } + remove_duplicates(rules); + commit(false); Nebula::instance().get_lcm()->trigger_updatesg(oid);