Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controllers management #93

Open
wants to merge 20 commits into
base: integration-0.8
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9bcb4e1
Add controller from rest plugin implemented
vicalro Jul 2, 2015
f36b843
Basic remove controller functionality for REST interface
vicalro Jul 7, 2015
88efc5d
implementation of list in xcli and in endpoint. It is still not glued…
vicalro Jul 7, 2015
978ca72
Implemented list IDs from LSI
vicalro Jul 8, 2015
00f592c
Implemented ID assigned when adding a new controller
vicalro Jul 9, 2015
16a2f39
Added warnings on add and remove controller malformed commands
vicalro Jul 9, 2015
ad421d6
Implementation of REST call show controller
vicalro Jul 15, 2015
d46f6f6
Added examples exec add/remove controller to xcli
vicalro Jul 20, 2015
1ec0b91
Changed the structure of the information of the controllers for bette…
vicalro Jul 20, 2015
9f334e9
Erased "rpc" from calls to the switch manager. Using only read lock w…
vicalro Jul 20, 2015
63f7247
Small fix in label of controller information
vicalro Jul 20, 2015
f7a42b0
Added Equal as a role for controllers and using get_role() in crofbas…
vicalro Jul 21, 2015
1902f12
Cleaning old commnents
vicalro Jul 21, 2015
73be2e2
Merge branch 'integration-0.8' into controllers_management
vicalro Jul 28, 2015
d4ee5e7
Following previuos order in register of REST calls
vicalro Jul 28, 2015
5448b49
Changed the way we handle errors in management of controllers with REST
vicalro Jul 28, 2015
302573f
Removed unnecessary spaces
vicalro Jul 28, 2015
34a16a1
Deleted unnecessary stringstreams
vicalro Jul 28, 2015
2f5295d
Polish of REST management of controllers
vicalro Jul 29, 2015
95ad31b
Fixed indentation and removed unnecessary try/catches
vicalro Jul 29, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/xdpd/management/plugins/config/openflow/lsi_scope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void lsi_scope::post_validate(libconfig::Setting& setting, bool dry_run){

//Connect(1..N-1)
for(std::vector<lsi_connection>::iterator it = (conns.begin()+1); it != conns.end(); ++it) {
switch_manager::rpc_connect_to_ctl(dpid, it->type, it->params);
switch_manager::connect_to_ctl(dpid, it->type, it->params);
}
}
}
1 change: 1 addition & 0 deletions src/xdpd/management/plugins/rest/delete-controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace delete_{
* Destroy an LSI
*/
void destroy_switch(const http::server::request &, http::server::reply &, boost::cmatch&);
void rem_ctl(const http::server::request &, http::server::reply &, boost::cmatch&);

} //namespace delete_
} //namespace controllers
Expand Down
6 changes: 6 additions & 0 deletions src/xdpd/management/plugins/rest/get-controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ namespace get{
void list_ports(const http::server::request &, http::server::reply &, boost::cmatch&);
void port_detail(const http::server::request &, http::server::reply &, boost::cmatch&);

/**
* Controllers
*/
void list_ctls(const http::server::request &, http::server::reply &, boost::cmatch&);
void show_ctl(const http::server::request &, http::server::reply &, boost::cmatch&);

} //namespace get
} //namespace controllers
} //namespace xdpd
Expand Down
4 changes: 4 additions & 0 deletions src/xdpd/management/plugins/rest/misc-controllers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm
html << "<li><b>/info/lsi/&lt;lsi_name&gt</b>: show logical switch instance(LSI) information" << std::endl;
html << "<li><b>/info/lsi/&lt;lsi_name&gt/table/&lt;num&gt/flows</b>: list LSI table flow entries" << std::endl;
html << "<li><b>/info/lsi/&lt;lsi_name&gt/group-table</b>: list LSI group table entries" << std::endl;
html << "<li><b>/info/lsi/&lt;lsi_name&gt/controllers</b>: list of controllers IDs" << std::endl;
html << "<li><b>/info/lsi/&lt;lsi_name&gt/controller/&lt;controller_id&gt</b>: show controller information" << std::endl;
html << "</ul>" << std::endl;

//POST
Expand All @@ -75,6 +77,7 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm

html << "<li><b>/mgmt/create/lsi</b>: create a LSI" << std::endl;
html << "<li><b>/mgmt/create/vlink/&lt;lsi1_name&gt/&lt;lsi2_name&gt</b>: create a virtual link between two LSIs" << std::endl;
html << "<li><b>/mgmt/add/controller/&lt;lsi_name&gt</b>: add a new controller to an LSI" << std::endl;

html << "</ul>" << std::endl;

Expand All @@ -83,6 +86,7 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm
html << "<ul>" << std::endl;

html << "<li><b>/mgmt/destroy/lsi/&lt;lsi_name&gt</b>: destroy an LSIs" << std::endl;
html << "<li><b>/mgmt/remove/controller/&lt;lsi_name&gt/&lt;controller_id&gt</b>: remove a controller from LSI" << std::endl;

html << "</ul>" << std::endl;

Expand Down
5 changes: 5 additions & 0 deletions src/xdpd/management/plugins/rest/put-controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ namespace put{
*/
void create_vlink(const http::server::request &, http::server::reply &, boost::cmatch&);

/*
* Add a new controller to the LSI
*/
void add_ctl(const http::server::request &, http::server::reply &, boost::cmatch&);

} //namespace put
} //namespace controllers
} //namespace xdpd
Expand Down
10 changes: 10 additions & 0 deletions src/xdpd/management/plugins/rest/rest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ static void srvthread (){
handler.register_get_path("/info/lsi/(\\w+)/table/([0-9]+)/flows", boost::bind(controllers::get::lsi_table_flows, _1, _2, _3));
handler.register_get_path("/info/lsi/(\\w+)/group-table", boost::bind(controllers::get::lsi_groups, _1, _2, _3));

//Controllers
handler.register_get_path("/info/lsi/(\\w+)/controllers", boost::bind(controllers::get::list_ctls, _1, _2, _3));
handler.register_get_path("/info/lsi/(\\w+)/controller/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3));

//
// POST
//
Expand All @@ -99,11 +103,17 @@ static void srvthread (){
handler.register_post_path("/mgmt/create/lsi", boost::bind(controllers::put::create_lsi, _1, _2, _3));
handler.register_put_path("/mgmt/create/vlink/(\\w+)/(\\w+)", boost::bind(controllers::put::create_vlink, _1, _2, _3));

// Controllers
handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3));

//
//DELETE
//
handler.register_delete_path("/mgmt/destroy/lsi/(\\w+)", boost::bind(controllers::delete_::destroy_switch, _1, _2, _3));

// Controllers
handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3));

//Recover host and port
parse_bind_addr(host, port);

Expand Down
194 changes: 194 additions & 0 deletions src/xdpd/management/plugins/rest/sw-controllers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,92 @@ void lsi_groups(const http::server::request &req,
rep.content = json_spirit::write(wrap, true);
}

void list_ctls(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){
std::string lsi_name;
uint64_t dpid;
std::list<rofl::cctlid> list;
json_spirit::Object table;

lsi_name = std::string(grps[1]);

// Get dpid
if(!switch_manager::exists_by_name(lsi_name)){
//Throw 404
std::stringstream ss;
ss<<"Invalid lsi '"<<lsi_name<<"'";
rep.content = ss.str();
rep.status = http::server::reply::not_found;
return;
}
dpid = switch_manager::get_switch_dpid(lsi_name);

try{
switch_manager::list_ctls(dpid, &list);
}catch(...){
throw "Unable to get list of ctls from lsi";
}

//Return data
std::list<std::string> list_str;
for(std::list<rofl::cctlid>::iterator it = list.begin(); it != list.end(); it++){
std::stringstream ss_tmp;
ss_tmp << it->get_ctlid();
list_str.push_back(ss_tmp.str());
}

json_spirit::Value ids_(list_str.begin(), list_str.end());
table.push_back(json_spirit::Pair("controller-ids", ids_));
rep.content = json_spirit::write(table, true);
}

void show_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){
std::string lsi_name; //, ctl_id;
uint64_t dpid, ctl_id;
controller_snapshot ctl_info;
json_spirit::Object j_wrap, j_ctl, j_list;

lsi_name = std::string(grps[1]);
ctl_id = atoi(std::string(grps[2]).c_str());


// Get dpid
if(!switch_manager::exists_by_name(lsi_name)){
//Throw 404
std::stringstream ss;
ss<<"Invalid lsi '"<<lsi_name<<"'";
rep.content = ss.str();
rep.status = http::server::reply::not_found;
return;
}

dpid = switch_manager::get_switch_dpid(lsi_name);

switch_manager::get_controller_info(dpid, ctl_id, ctl_info);

j_ctl.push_back(json_spirit::Pair("id", ctl_info.id));
j_ctl.push_back(json_spirit::Pair("channel-status", ctl_info.get_status_str()));
j_ctl.push_back(json_spirit::Pair("mode", ctl_info.get_role_str()));

std::list<controller_conn_snapshot>::const_iterator it;
for(it=ctl_info.conn_list.begin(); it != ctl_info.conn_list.end(); ++it){
json_spirit::Object j_conn;
j_conn.push_back(json_spirit::Pair("protocol-type", it->get_proto_type_str()));
j_conn.push_back(json_spirit::Pair("ip", it->ip));
j_conn.push_back(json_spirit::Pair("port", it->port));

std::stringstream ss;
ss << it->id;
j_list.push_back(json_spirit::Pair(ss.str(), j_conn));

}

j_ctl.push_back(json_spirit::Pair("connections", j_list));

//Return data
j_wrap.push_back(json_spirit::Pair("controller", j_ctl));
rep.content = json_spirit::write(j_wrap, true);
}

} //namespace get


Expand Down Expand Up @@ -358,6 +444,83 @@ void create_lsi(const http::server::request &req, http::server::reply &rep, boos
//There is no need to return anything
}


void add_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){

//call switch_manager to add a new controller to the LSI
// get IP & port from the req parameter (json?)
// check IP & port (if there is already a controller there, send error message)
std::string proto, ip, port;
enum rofl::csocket::socket_type_t socket_type;
rofl::cparams socket_params;
json_spirit::Object table;
uint64_t assigned_id;

//Perform security checks
if(!authorised(req,rep)) return;

std::string lsi_name = std::string(grps[1]);

//Check if LSI exists;
if(!switch_manager::exists_by_name(lsi_name)){
//Throw 404
std::stringstream ss;
ss<<"Invalid lsi '"<<lsi_name<<"'";
rep.content = ss.str();
rep.status = http::server::reply::not_found;
return;
}

// Get dpid check for failure
uint64_t dpid = switch_manager::get_switch_dpid(lsi_name);

// Parse data (protocol, IP & port)
try{
//Parse the input
json_spirit::Value val;

//First object must be "lsi"
json_spirit::read(req.content, val);

json_spirit::Object obj = val.get_obj();
obj = json_spirit::find_value(obj, "ctl").get_obj();

//Fill in parameters
proto = json_spirit::find_value(obj, "proto").get_str();
ip = json_spirit::find_value(obj, "ip").get_str();
port = json_spirit::find_value(obj, "port").get_str();

}catch(...){
std::stringstream ss;
ss<<"Unable to parse arguments for add controller";
rep.content = ss.str();
rep.status = http::server::reply::bad_request;
return;
}


//TODO Check parameters received (proto, ip & port)
if ( proto == "tcp" ){
socket_type = rofl::csocket::SOCKET_TYPE_PLAIN;
} else {
// TODO Other types not yet supported (SOCKET_TYPE_OPENSSL)
std::stringstream ss;
ss<<"Invalid protocol '"<<lsi_name<<"'";
rep.content = ss.str();
rep.status = http::server::reply::bad_request;
return;
}
socket_params = rofl::csocket::get_default_params(socket_type);
socket_params.set_param(rofl::csocket::PARAM_KEY_REMOTE_HOSTNAME) = ip;
socket_params.set_param(rofl::csocket::PARAM_KEY_REMOTE_PORT) = port;

assigned_id = switch_manager::connect_to_ctl(dpid, socket_type, socket_params);

//Return assigned ID
table.push_back(json_spirit::Pair("controller-id", assigned_id));
rep.content = json_spirit::write(table, true);
}

} //namespace put

namespace delete_{
Expand Down Expand Up @@ -395,6 +558,37 @@ void destroy_switch(const http::server::request &req, http::server::reply &rep,
}
}

void rem_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){

std::string lsi_name;
std::string ctlid_str;
uint64_t dpid, ctl_id;

//Perform security checks
if(!authorised(req,rep)) return;

lsi_name = std::string(grps[1]);
ctlid_str = std::string(grps[2]);

//Check if LSI exists;
if(!switch_manager::exists_by_name(lsi_name)){
std::stringstream ss;
ss<<"Invalid lsi '"<<lsi_name<<"'";
rep.content = ss.str();
rep.status = http::server::reply::not_found;
return;
}

//Get dpid
dpid = switch_manager::get_switch_dpid(lsi_name);

//Get controller id
ctl_id = atoi(ctlid_str.c_str());
rofl::cctlid ctlid(ctl_id);

switch_manager::disconnect_from_ctl(dpid, ctlid);
}

} //namespace delete
} //namespace controllers
} //namespace xdpd
Loading