- mac address parser/serializer - move out WSPathNetwork from rest.py - introduce wspath.py for URI parser which will be commonly used and moved WSPathNetwork into it.
Signed-off-by: Isaku Yamahata <[email protected]> --- ryu/app/rest.py | 126 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 101 insertions(+), 25 deletions(-) diff --git a/ryu/app/rest.py b/ryu/app/rest.py index 3116424..8993ab2 100644 --- a/ryu/app/rest.py +++ b/ryu/app/rest.py @@ -14,12 +14,15 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import json +from ryu.exception import MacAddressAlreadyExist from ryu.exception import NetworkNotFound, NetworkAlreadyExist from ryu.exception import PortNotFound, PortAlreadyExist from ryu.app.wsapi import WSPathComponent from ryu.app.wsapi import WSPathExtractResult from ryu.app.wsapi import WSPathStaticString from ryu.app.wsapi import wsapi +from ryu.app.wspath import WSPathNetwork +from ryu.lib import mac # REST API @@ -51,45 +54,62 @@ from ryu.app.wsapi import wsapi # # remove a set of dpid and port # DELETE /v1.0/networks/{network-id}/{dpid}_{port-id} - -# We store networks and ports like the following: # -# {network_id: [(dpid, port), ... -# {3: [(3,4), (4,7)], 5: [(3,6)], 1: [(5,6), (4,5), (4, 10)]} +# get the list of mac addresses of dpid and port +# GET /v1.0/networks/{network-id}/{dpid}_{port-id}/macs/ +# +# register a new mac address for dpid and port +# Fail if mac address is already registered or the mac address is used +# for other ports of the same network-id +# POST /v1.0/networks/{network-id}/{dpid}_{port-id}/macs/{mac} +# +# update a new mac address for dpid and port +# Success as nop even if same mac address is already registered. +# For now, changing mac address is not allows as it fails. +# PUT /v1.0/networks/{network-id}/{dpid}_{port-id}/macs/{mac} +# +# For now DELETE /v1.0/networks/{network-id}/{dpid}_{port-id}/macs/{mac} +# is not supported. mac address is released when port is deleted. # -class WSPathNetwork(WSPathComponent): - """ Match a network id string """ +class WSPathPort(WSPathComponent): + """ Match a {dpid}_{port-id} string """ def __str__(self): - return "{network-id}" + return "{dpid}_{port-id}" def extract(self, pc, _data): if pc == None: return WSPathExtractResult(error="End of requested URI") - return WSPathExtractResult(value=pc) + try: + dpid_str, port_str = pc.split('_') + dpid = int(dpid_str, 16) + port = int(port_str) + except ValueError: + return WSPathExtractResult(error="Invalid format: %s" % pc) + + return WSPathExtractResult(value={'dpid': dpid, 'port': port}) -class WSPathPort(WSPathComponent): - """ Match a {dpid}_{port-id} string """ +class WSPathMacAddress(WSPathComponent): + """ Match a {mac} string: %02x:%02x:%02x:%02x:%02x:%02x + Internal representation of mac address is string[6]""" def __str__(self): - return "{dpid}_{port-id}" + return "{mac}" - def extract(self, pc, _data): + def extract(self, pc, data): if pc == None: return WSPathExtractResult(error="End of requested URI") try: - dpid_str, port_str = pc.split('_') - dpid = int(dpid_str, 16) - port = int(port_str) + mac_addr = mac.haddr_to_bin(pc) except ValueError: return WSPathExtractResult(error="Invalid format: %s" % pc) - return WSPathExtractResult(value={'dpid': dpid, 'port': port}) + return WSPathExtractResult(value=mac_addr) class restapi: @@ -141,10 +161,14 @@ class restapi: request.setHeader("Content-Type", 'application/json') return body + @staticmethod + def _get_param_port(data): + return (data['{network-id}'], + data['{dpid}_{port-id}']['dpid'], + data['{dpid}_{port-id}']['port']) + def create_port_handler(self, request, data): - network_id = data['{network-id}'] - dpid = data['{dpid}_{port-id}']['dpid'] - port = data['{dpid}_{port-id}']['port'] + (network_id, dpid, port) = self._get_param_port(data) try: self.nw.create_port(network_id, dpid, port) @@ -156,9 +180,7 @@ class restapi: return "" def update_port_handler(self, request, data): - network_id = data['{network-id}'] - dpid = data['{dpid}_{port-id}']['dpid'] - port = data['{dpid}_{port-id}']['port'] + (network_id, dpid, port) = self._get_param_port(data) try: self.nw.update_port(network_id, dpid, port) @@ -168,9 +190,7 @@ class restapi: return "" def remove_port_handler(self, request, data): - network_id = data['{network-id}'] - dpid = data['{dpid}_{port-id}']['dpid'] - port = data['{dpid}_{port-id}']['port'] + (network_id, dpid, port) = self._get_param_port(data) try: self.nw.remove_port(network_id, dpid, port) @@ -179,6 +199,48 @@ class restapi: return "" + def list_mac_handler(self, request, data): + (_network_id, dpid, port_no) = self._get_param_port(data) + + try: + body = json.dumps([mac.haddr_to_str(mac_addr) for mac_addr in + self.nw.list_mac(dpid, port_no)]) + except PortNotFound: + request.setResponseCode(404) + return "" + + request.setHeader("Content-Type", 'application/json') + return body + + @staticmethod + def _get_param_mac(data): + return (data['{network-id}'], + data['{dpid}_{port-id}']['dpid'], + data['{dpid}_{port-id}']['port'], + data['{mac}']) + + def create_mac_handler(self, request, data): + (network_id, dpid, port_no, mac_addr) = self._get_param_mac(data) + + try: + self.nw.create_mac(network_id, dpid, port_no, mac_addr) + except MacAddressAlreadyExist: + request.setResponseCode(409) + except PortNotFound: + request.setResponseCode(404) + + return "" + + def update_mac_handler(self, request, data): + (network_id, dpid, port_no, mac_addr) = self._get_param_mac(data) + + try: + self.nw.update_mac(network_id, dpid, port_no, mac_addr) + except PortNotFound: + request.setResponseCode(404) + + return "" + def register(self): path_networks = (WSPathStaticString('networks'), ) self.api.register_request(self.list_networks_handler, "GET", @@ -214,3 +276,17 @@ class restapi: self.api.register_request(self.remove_port_handler, "DELETE", path_port, "remove a set of dpid and port") + + path_macs = path_port + (WSPathStaticString('macs'), ) + self.api.register_request(self.list_mac_handler, "GET", + path_macs, + "get the list of mac addresses") + + path_mac = path_macs + (WSPathMacAddress(), ) + self.api.register_request(self.create_mac_handler, "POST", + path_mac, + "register a new mac address for a port") + + self.api.register_request(self.update_mac_handler, "PUT", + path_mac, + "update a mac address for a port") -- 1.7.1.1 ------------------------------------------------------------------------------ Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
