Skip to content

Commit

Permalink
Allow custom configs with LBaaS
Browse files Browse the repository at this point in the history
This fix enables a new field "custom-attr" in loadbalancer_pool
properties in the schema.

Change-Id: I17eecc2fedea4d1d3889b7e114e99732ac2eecc9
Closes-Bug: #1475393

Allow custom configs with LBaaS

This fix commits the vrouter agent code to read
the custom_attributes from ifmap node and copy it
to config.json file which the haproxy parser
would read. Added missing '}'. Incorporating the
comments

Closes-Bug: #1475393
Change-Id: I6f22f4f537c97c48b2283971b2959c9be5931361

Conflicts:
	src/vnsw/agent/oper/loadbalancer.cc
	src/vnsw/agent/oper/loadbalancer_config.cc
	src/vnsw/agent/oper/loadbalancer_config.h

Change-Id: Iea0aff5589a21e3c802e4e63633a1d74f22cdeaf
  • Loading branch information
Varun Lodaya authored and Varun Lodaya committed Sep 17, 2015
1 parent 7fe1a46 commit 1841342
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/schema/loadbalancer.xsd
Expand Up @@ -85,6 +85,10 @@
Link('loadbalancer-pool-service-appliance-set',
'loadbalancer-pool', 'service-appliance-set', ['ref']) -->

<xsd:element name="loadbalancer-pool-custom-attributes" type="KeyValuePairs"/>
<!--#IFMAP-SEMANTICS-IDL
Property('loadbalancer-pool-custom-attributes', 'loadbalancer-pool') -->

<xsd:element name="loadbalancer-member" type="ifmap:IdentityType"/>
<xsd:element name="loadbalancer-pool-loadbalancer-member"/>
<!--#IFMAP-SEMANTICS-IDL
Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/oper/loadbalancer.cc
Expand Up @@ -90,7 +90,6 @@ static void PropertiesAddHealthmonitor(
healthmon->properties()));
}


bool Loadbalancer::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
LoadBalancerResp *resp = static_cast<LoadBalancerResp*> (sresp);

Expand Down Expand Up @@ -294,6 +293,7 @@ void LoadbalancerTable::CalculateProperties(DBGraph *graph, IFMapNode
autogen::LoadbalancerPool *pool =
static_cast<autogen::LoadbalancerPool *>(node->GetObject());
properties->set_pool_properties(pool->properties());
properties->set_custom_attributes(pool->custom_attributes());

for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
iter != node->end(graph); ++iter) {
Expand Down
169 changes: 169 additions & 0 deletions src/vnsw/agent/oper/loadbalancer_config.cc
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
*/

#include "loadbalancer_config.h"

#include <cerrno>
#include <fstream>
#include <boost/assign/list_of.hpp>
#include "base/logging.h"
#include "agent.h"
#include "init/agent_param.h"

#include "loadbalancer_properties.h"

using namespace std;
using boost::assign::map_list_of;

LoadbalancerConfig::LoadbalancerConfig(Agent *agent)
: agent_(agent) {
}

void LoadbalancerConfig::GeneratePool(
ostream *out, const boost::uuids::uuid &pool_id,
const LoadbalancerProperties &props) const {
const autogen::LoadbalancerPoolType &pool = props.pool_properties();

ostringstream ostr;
ostr << " \"pool\":{" << endl
<< " \"id\":\"" << pool_id << "\"," << endl
<< " \"protocol\":\"" << pool.protocol << "\"," << endl
<< " \"method\":\"" << pool.loadbalancer_method << "\"," << endl
<< " \"admin-state\":" << std::boolalpha << pool.admin_state
<< endl
<< " }," << endl;
*out << ostr.str();
}

void LoadbalancerConfig::GenerateVip(
ostream *out, const LoadbalancerProperties &props) const {

const autogen::VirtualIpType &vip = props.vip_properties();
ostringstream ostr;
ostr << " \"vip\":{" << endl
<< " \"id\":\"" << props.vip_uuid() << "\"," << endl
<< " \"address\":\"" << vip.address <<"\"," << endl
<< " \"port\":" << vip.protocol_port << "," << endl
<< " \"protocol\":\"" << vip.protocol <<"\"," << endl
<< " \"connection-limit\":" << vip.connection_limit << ","
<< endl
<< " \"persistence-cookie-name\": \""
<< vip.persistence_cookie_name << "\"," << endl
<< " \"persistence-type\": \"" << vip.persistence_type << "\","
<< endl
<< " \"admin-state\":" << std::boolalpha << vip.admin_state << endl
<< " }," << endl;
*out << ostr.str();
}

void LoadbalancerConfig::GenerateMembers(
ostream *out, const LoadbalancerProperties &props) const {

ostringstream ostr;
ostr << " \"members\":[" << endl;
int count = 0;
for (LoadbalancerProperties::MemberMap::const_iterator iter =
props.members().begin();
iter != props.members().end(); ++iter) {
const autogen::LoadbalancerMemberType &member = iter->second;
if (count) {
ostr << "," << endl;
}
ostr << " {" << endl
<< " \"id\":\"" << iter->first << "\"," << endl
<< " \"address\":\"" << member.address << "\"," << endl
<< " \"port\":" << member.protocol_port << "," << endl
<< " \"weight\":" << member.weight << "," << endl
<< " \"admin-state\":" << std::boolalpha
<< member.admin_state << endl
<< " }";
count++;
}
if (count) {
ostr << endl;
}
ostr << " ]," << endl;
*out << ostr.str();
}

void LoadbalancerConfig::GenerateHealthMonitors(
ostream *out, const LoadbalancerProperties &props) const {

ostringstream ostr;
ostr << " \"healthmonitors\":[" << endl;
int count = 0;
for (LoadbalancerProperties::HealthmonitorMap::const_iterator iter =
props.healthmonitors().begin();
iter != props.healthmonitors().end(); ++iter) {
const autogen::LoadbalancerHealthmonitorType &hm = iter->second;
if (count) {
ostr << "," << endl;
}
ostr << " {" << endl
<< " \"id\":\"" << iter->first << "\"," << endl
<< " \"type\": \"" << hm.monitor_type << "\"," << endl
<< " \"delay\":" << hm.delay << "," << endl
<< " \"timeout\":" << hm.timeout << "," << endl
<< " \"max-retries\":" << hm.max_retries << "," << endl
<< " \"http-method\": \"" << hm.http_method << "\"," << endl
<< " \"url\": \"" << hm.url_path << "\"," << endl
<< " \"expected-codes\": \"" << hm.expected_codes << "\","
<< endl
<< " \"admin-state\":" << std::boolalpha << hm.admin_state
<< endl
<< " }";
count++;
}
if (count) {
ostr << endl;
}
ostr << " ]," << endl;
*out << ostr.str();
}

void LoadbalancerConfig::GenerateCustomAttributes(
ostream *out, const LoadbalancerProperties &props) const {
const std::vector<autogen::KeyValuePair>
&custom_attributes = props.custom_attributes();
ostringstream ostr;
autogen::KeyValuePairs::const_iterator curr_iter, next_iter, end_iter;
curr_iter = custom_attributes.begin();
end_iter = custom_attributes.end();

ostr << " \"custom-attributes\":{" << endl;

while (curr_iter != end_iter) {
next_iter = curr_iter + 1;
const autogen::KeyValuePair element = (*curr_iter);
ostr << " \"" << element.key << "\":\"" << element.value << "\"";
if (next_iter == end_iter) {
ostr << endl;
break;
}
ostr << "," << endl;
curr_iter = next_iter;
}
ostr << " }" << endl;
*out << ostr.str();
}

void LoadbalancerConfig::GenerateConfig(
const string &filename, const boost::uuids::uuid &pool_id,
const LoadbalancerProperties &props) const {
ofstream fs(filename.c_str());
if (fs.fail()) {
LOG(ERROR, "File create " << filename << ": " << strerror(errno));
}

fs << "{" << endl;
fs << " \"ssl-crt\":\"" << agent_->params()->si_lb_ssl_cert_path()
<< "\"," << endl;
GeneratePool(&fs, pool_id, props);
GenerateVip(&fs, props);
GenerateMembers(&fs, props);
GenerateHealthMonitors(&fs, props);
GenerateCustomAttributes(&fs, props);
fs << "}" << endl;
fs.close();
}
38 changes: 38 additions & 0 deletions src/vnsw/agent/oper/loadbalancer_config.h
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
*/

#include <map>
#include <string>
#include <ostream>
#include <boost/uuid/uuid.hpp>
#include "base/util.h"

class LoadbalancerProperties;
class Agent;

class LoadbalancerConfig {
public:
LoadbalancerConfig(Agent *);

void GenerateConfig(const std::string &filename,
const boost::uuids::uuid &pool_id,
const LoadbalancerProperties &props) const;

private:
void GenerateVip(std::ostream *out,
const LoadbalancerProperties &props) const;
void GeneratePool(std::ostream *out,
const boost::uuids::uuid &pool_id,
const LoadbalancerProperties &props) const;
void GenerateMembers(std::ostream *out,
const LoadbalancerProperties &props) const;
void GenerateHealthMonitors(std::ostream *out,
const LoadbalancerProperties &props) const;
void GenerateCustomAttributes(std::ostream *out,
const LoadbalancerProperties &props) const;

Agent *agent_;

DISALLOW_COPY_AND_ASSIGN(LoadbalancerConfig);
};
50 changes: 50 additions & 0 deletions src/vnsw/agent/oper/loadbalancer_properties.cc
Expand Up @@ -125,6 +125,48 @@ void MapDiff(const MapType &lhs, const MapType &rhs, Comparator comp,
}
}

int CustomAttributesCompare(const std::vector<autogen::KeyValuePair> &lhs,
const std::vector<autogen::KeyValuePair> &rhs) {
autogen::KeyValuePairs::const_iterator iter1 = lhs.begin();
autogen::KeyValuePairs::const_iterator iter2 = rhs.begin();
int ret = 0;

while (iter1 != lhs.end() && iter2 != rhs.end()) {
if ((ret = iter1->key.compare(iter2->key)) != 0) {
return ret;
}
if ((ret = iter1->value.compare(iter2->value)) != 0) {
return ret;
}
++iter1;
++iter2;
}

if (iter1 != lhs.end()) {
return 1;
}
if (iter2 != rhs.end()) {
return -1;
}
return 0;
}

void CustomAttributesDiff(const std::vector<autogen::KeyValuePair> &lhs,
const std::vector<autogen::KeyValuePair> &rhs,
std::stringstream *ss) {
autogen::KeyValuePairs::const_iterator iter1 = lhs.begin();
autogen::KeyValuePairs::const_iterator iter2 = rhs.begin();

while (iter1 != lhs.end()) {
*ss << " -" << iter1->key << ": " << iter1->value;
++iter1;
}
while (iter2 != rhs.end()) {
*ss << " +" << iter2->key << ": " << iter2->value;
++iter2;
}
}

#define COMPARE_PROPERTY(Xname) \
do { \
int res = compare(Xname, rhs.Xname); \
Expand Down Expand Up @@ -152,8 +194,14 @@ int LoadbalancerProperties::CompareTo(const LoadbalancerProperties &rhs) const {
}

result = MapCompare(monitors_, rhs.monitors_, CompareMonitor);
if (result) {
return result;
}

result = CustomAttributesCompare(custom_attributes_, rhs.custom_attributes_);
return result;
}

#undef COMPARE_PROPERTY

#define DIFF_PROPERTY(Xss, Xname)\
Expand Down Expand Up @@ -187,6 +235,8 @@ std::string LoadbalancerProperties::DiffString(
MapDiff(current->members_, members_, CompareMember, &ss);
ss << " Monitors:";
MapDiff(current->monitors_, monitors_, CompareMonitor, &ss);
ss << " Custom Attributes:";
CustomAttributesDiff(current->custom_attributes_, custom_attributes_, &ss);

return ss.str();
}
Expand Down
9 changes: 9 additions & 0 deletions src/vnsw/agent/oper/loadbalancer_properties.h
Expand Up @@ -62,12 +62,21 @@ class LoadbalancerProperties {
return &monitors_;
}

const std::vector<autogen::KeyValuePair> &custom_attributes() const {
return custom_attributes_;
}

void set_custom_attributes(const std::vector<autogen::KeyValuePair> &custom_attributes) {
custom_attributes_ = custom_attributes;
}

private:
autogen::LoadbalancerPoolType pool_;
boost::uuids::uuid vip_uuid_;
autogen::VirtualIpType vip_;
MemberMap members_;
HealthmonitorMap monitors_;
std::vector<autogen::KeyValuePair> custom_attributes_;
};

#endif // VNSW_AGENT_OPER_LOADBALANCER_PROPERTIES_H__

0 comments on commit 1841342

Please sign in to comment.