Soft Patch Panel
 help / color / mirror / Atom feed
From: oda@valinux.co.jp
To: spp@dpdk.org, ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp
Subject: [spp] [PATCH v4 09/14] spp-ctl: add spp command interfaces
Date: Fri,  5 Oct 2018 12:57:52 +0900	[thread overview]
Message-ID: <20181005035757.23122-10-oda@valinux.co.jp> (raw)
In-Reply-To: <20181005035757.23122-1-oda@valinux.co.jp>

From: Itsuro Oda <oda@valinux.co.jp>

Add API classes for each of SPP processes.

Signed-off-by: Itsuro Oda <oda@valinux.co.jp>
---
 src/spp-ctl/spp_proc.py | 187 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100644 src/spp-ctl/spp_proc.py

diff --git a/src/spp-ctl/spp_proc.py b/src/spp-ctl/spp_proc.py
new file mode 100644
index 0000000..aa83b76
--- /dev/null
+++ b/src/spp-ctl/spp_proc.py
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
+
+import bottle
+import eventlet
+import json
+import logging
+
+import spp_ctl
+
+
+LOG = logging.getLogger(__name__)
+
+ID_PRIMARY = 0
+TYPE_PRIMARY = "primary"
+TYPE_VF = "vf"
+TYPE_NFV = "nfv"
+
+
+def exec_command(func):
+    """Decorator for Sending command and receiving reply.
+
+    Define the common function for sending command and receiving reply
+    as a decorator. Each of methods for executing command has only to
+    return command string.
+
+    exp)
+    @exec_command
+    def some_command(self, ...):
+        return "command string of some_command"
+    """
+    def wrapper(self, *args, **kwargs):
+        with self.sem:
+            command = func(self, *args, **kwargs)
+            LOG.info("%s(%d) command executed: %s", self.type, self.id,
+                     command)
+            data = spp_ctl.Controller._send_command(self.conn, command)
+            if data is None:
+                raise RuntimeError("%s(%d): %s: no-data returned" %
+                                   (self.type, self.id, command))
+            LOG.debug("reply: %s", data)
+            return self._decode_reply(data)
+    return wrapper
+
+
+class SppProc(object):
+    def __init__(self, proc_type, id, conn):
+        self.id = id
+        self.type = proc_type
+        # NOTE: executing command is serialized by using a semaphore
+        # for each process.
+        self.sem = eventlet.semaphore.Semaphore(value=1)
+        self.conn = conn
+
+
+class VfProc(SppProc):
+
+    def __init__(self, id, conn):
+        super(VfProc, self).__init__(TYPE_VF, id, conn)
+
+    @staticmethod
+    def _decode_reply(data):
+        data = json.loads(data)
+        result = data["results"][0]
+        if result["result"] == "error":
+            msg = result["error_details"]["message"]
+            raise bottle.HTTPError(400, "command error: %s" % msg)
+        return data
+
+    @staticmethod
+    def _decode_client_id(data):
+        try:
+            data = VfProc._decode_reply(data)
+            return data["client_id"]
+        except:
+            return None
+
+    @exec_command
+    def get_status(self):
+        return "status"
+
+    @exec_command
+    def start_component(self, comp_name, core_id, comp_type):
+        return ("component start {comp_name} {core_id} {comp_type}"
+                .format(**locals()))
+
+    @exec_command
+    def stop_component(self, comp_name):
+        return "component stop {comp_name}".format(**locals())
+
+    @exec_command
+    def port_add(self, port, direction, comp_name, op, vlan_id, pcp):
+        command = "port add {port} {direction} {comp_name}".format(**locals())
+        if op != "none":
+            command += " %s" % op
+            if op == "add_vlantag":
+                command += " %d %d" % (vlan_id, pcp)
+        return command
+
+    @exec_command
+    def port_del(self, port, direction, comp_name):
+        return "port del {port} {direction} {comp_name}".format(**locals())
+
+    @exec_command
+    def set_classifier_table(self, mac_address, port):
+        return ("classifier_table add mac {mac_address} {port}"
+                .format(**locals()))
+
+    @exec_command
+    def clear_classifier_table(self, mac_address, port):
+        return ("classifier_table del mac {mac_address} {port}"
+                .format(**locals()))
+
+    @exec_command
+    def set_classifier_table_with_vlan(self, mac_address, port,
+                                       vlan_id):
+        return ("classifier_table add vlan {vlan_id} {mac_address} {port}"
+                .format(**locals()))
+
+    @exec_command
+    def clear_classifier_table_with_vlan(self, mac_address, port,
+                                         vlan_id):
+        return ("classifier_table del vlan {vlan_id} {mac_address} {port}"
+                .format(**locals()))
+
+
+class NfvProc(SppProc):
+
+    def __init__(self, id, conn):
+        super(NfvProc, self).__init__(TYPE_NFV, id, conn)
+
+    @staticmethod
+    def _decode_reply(data):
+        return data.strip('\0')
+
+    @staticmethod
+    def _decode_client_id(data):
+        try:
+            return int(NfvProc._decode_reply(data))
+        except:
+            return None
+
+    @exec_command
+    def get_status(self):
+        return "status"
+
+    @exec_command
+    def port_add(self, if_type, if_num):
+        return "add {if_type} {if_num}".format(**locals())
+
+    @exec_command
+    def port_del(self, if_type, if_num):
+        return "del {if_type} {if_num}".format(**locals())
+
+    @exec_command
+    def patch_add(self, src_port, dst_port):
+        return "patch {src_port} {dst_port}".format(**locals())
+
+    @exec_command
+    def patch_reset(self):
+        return "patch reset"
+
+    @exec_command
+    def forward(self):
+        return "forward"
+
+    @exec_command
+    def stop(self):
+        return "stop"
+
+
+class PrimaryProc(SppProc):
+
+    def __init__(self, conn):
+        super(PrimaryProc, self).__init__(TYPE_PRIMARY, ID_PRIMARY, conn)
+
+    @staticmethod
+    def _decode_reply(data):
+        return data.strip('\0')
+
+    @exec_command
+    def status(self):
+        return "status"
+
+    @exec_command
+    def clear(self):
+        return "clear"
-- 
2.17.1

  parent reply	other threads:[~2018-10-05  3:58 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-12 23:25 [spp] [PATCH] spp-ctl: SPP controller with Web API Itsuro ODA
2018-09-18 10:00 ` Yasufumi Ogawa
2018-09-18 21:40   ` Itsuro ODA
2018-10-05  1:37 ` [spp] [PATCH v3 00/13] " oda
2018-10-05  1:37   ` [spp] [PATCH v3 01/13] docs: add overview of spp-ctl oda
2018-10-05  1:37   ` [spp] [PATCH v3 02/13] docs: add API reference " oda
2018-10-05  1:37   ` [spp] [PATCH v3 03/13] docs: add index " oda
2018-10-05  1:37   ` [spp] [PATCH v3 04/13] project: add requirements.txt for spp-ctl oda
2018-10-05  1:37   ` [spp] [PATCH v3 05/13] docs: add spp-ctl to index of doc root oda
2018-10-05  1:37   ` [spp] [PATCH v3 06/13] spp-ctl: add entry point oda
2018-10-05  1:37   ` [spp] [PATCH v3 07/13] spp-ctl: add Controller class oda
2018-10-05  1:37   ` [spp] [PATCH v3 08/13] spp-ctl: add web API handler oda
2018-10-05  1:37   ` [spp] [PATCH v3 09/13] spp-ctl: add spp command interfaces oda
2018-10-05  1:37   ` [spp] [PATCH v3 10/13] spp-ctl: update parsing spp_nfv status oda
2018-10-05  1:37   ` [spp] [PATCH v3 11/13] docs: add request examples of spp-ctl oda
2018-10-05  1:37   ` [spp] [PATCH v3 12/13] docs: correct directives " oda
2018-10-05  1:37   ` [spp] [PATCH v3 13/13] docs: add labels and captions for tables oda
2018-10-05  3:57 ` [spp] [PATCH v4 00/14] spp-ctl: SPP controller with Web API oda
2018-10-05  3:57   ` [spp] [PATCH v4 01/14] docs: add overview of spp-ctl oda
2018-10-05  3:57   ` [spp] [PATCH v4 02/14] docs: add API reference " oda
2018-10-05  3:57   ` [spp] [PATCH v4 03/14] docs: add index " oda
2018-10-05  3:57   ` [spp] [PATCH v4 04/14] project: add requirements.txt for spp-ctl oda
2018-10-05  3:57   ` [spp] [PATCH v4 05/14] docs: add spp-ctl to index of doc root oda
2018-10-05  3:57   ` [spp] [PATCH v4 06/14] spp-ctl: add entry point oda
2018-10-05  3:57   ` [spp] [PATCH v4 07/14] spp-ctl: add Controller class oda
2018-10-05  3:57   ` [spp] [PATCH v4 08/14] spp-ctl: add web API handler oda
2018-10-05  3:57   ` oda [this message]
2018-10-05  3:57   ` [spp] [PATCH v4 10/14] spp-ctl: update parsing spp_nfv status oda
2018-10-05  3:57   ` [spp] [PATCH v4 11/14] docs: add request examples of spp-ctl oda
2018-10-05  3:57   ` [spp] [PATCH v4 12/14] docs: correct directives " oda
2018-10-05  3:57   ` [spp] [PATCH v4 13/14] docs: add labels and captions for tables oda
2018-10-05  3:57   ` [spp] [PATCH v4 14/14] spp-ctl: fix incorrect URL oda
2018-10-09  2:01   ` [spp] [PATCH v4 00/14] spp-ctl: SPP controller with Web API Yasufumi Ogawa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181005035757.23122-10-oda@valinux.co.jp \
    --to=oda@valinux.co.jp \
    --cc=ferruh.yigit@intel.com \
    --cc=ogawa.yasufumi@lab.ntt.co.jp \
    --cc=spp@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).