Soft Patch Panel
 help / color / mirror / Atom feed
From: ogawa.yasufumi@lab.ntt.co.jp
To: ferruh.yigit@intel.com, spp@dpdk.org
Cc: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
Subject: [spp] [PATCH 09/13] controller: add do_topo to shell.py
Date: Tue,  6 Mar 2018 19:50:51 +0900	[thread overview]
Message-ID: <20180306105055.65210-10-ogawa.yasufumi@lab.ntt.co.jp> (raw)
In-Reply-To: <20180306105055.65210-1-ogawa.yasufumi@lab.ntt.co.jp>

From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

'topo' is an experimental command for SPP controller to outptu topology
of network configuration. It enables to display a graphical image of
network configuration on terminal, or browser for which websocket
server is running with.

'topo' command supports four types of output. For multiple output
support, it uses graphviz, imagemagick and other external tools.
* terminal (but very few terminals supporting to display images)
* browser (websocket server is required)
* image file (jpg, png, bmp)
* text (dot, json, yaml)

Here is a list of required tools for 'topo'. Notice that SPP controller
and 'topo' command support MacOS on a remote host.
* graphviz
* imagemagick
* libsixel-bin (for Ubuntu) and terminal app supporting img2sixel
* iTerm2 and imgcat (for MacOS)

For terminal, only few terminal applications are supported. You can use
mlterm or xterm for which 'img2sixel' supports on linux
or iTerm on MacOS. If you use iTerm2, you have to get a shell script
'imgcat' from [1] and save it as
'spp/src/controller/3rd_party/imgcat.sh'.

[1] https://iterm2.com/documentation-images.html

For browser support, you are required to install websocket libraries and
use 'spp_ws' tool. 'spp_ws' is not released yet, but soon.

There are some example usecases.

(1) Display on terminal or browser.
spp > topo term
spp > topo http

(2) Output to a file.
spp > topo myconfig.jpg
spp > topo myconfig dot

This update is only for 'shell.py' and requires a module file 'topo.py'
in which methods for 'topo' command are implemented.

Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
 src/controller/shell.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 1 deletion(-)

diff --git a/src/controller/shell.py b/src/controller/shell.py
index c5ef82d..8a0580a 100644
--- a/src/controller/shell.py
+++ b/src/controller/shell.py
@@ -7,6 +7,7 @@ from shell_lib import common
 import spp_common
 from spp_common import logger
 import subprocess
+import topo
 
 
 class Shell(cmd.Cmd, object):
@@ -481,7 +482,89 @@ class Shell(cmd.Cmd, object):
         from pprint import pprint
         if args == '':
             pprint(vars(self))
-            pprint(self.__class__.__name__)
+
+    def do_topo(self, args):
+        """Output network topology
+
+        Support four types of output.
+        * terminal (but very few terminals supporting to display images)
+        * browser (websocket server is required)
+        * image file (jpg, png, bmp)
+        * text (dot, json, yaml)
+
+        spp > topo term  # terminal
+        spp > topo http  # browser
+        spp > topo network_conf.jpg  # image
+        spp > topo network_conf.dot  # text
+        """
+
+        if len(spp_common.SECONDARY_LIST) == 0:
+            message = "secondary not exist"
+            print(message)
+            self.response(self.CMD_NOTREADY, message)
+        else:
+            tp = topo.Topo(
+                spp_common.SECONDARY_LIST,
+                spp_common.MAIN2SEC,
+                spp_common.SEC2MAIN)
+            args_ary = args.split()
+            if len(args_ary) == 0:
+                print("Usage: topo dst [ftype]")
+                return False
+            elif (args_ary[0] == "term") or (args_ary[0] == "http"):
+                res_ary = tp.show(args_ary[0])
+            elif len(args_ary) == 1:
+                ftype = args_ary[0].split(".")[-1]
+                res_ary = tp.output(args_ary[0], ftype)
+            elif len(args_ary) == 2:
+                res_ary = tp.output(args_ary[0], args_ary[1])
+            else:
+                print("Usage: topo dst [ftype]")
+                return False
+            self.response(self.CMD_OK, json.dumps(res_ary))
+
+    def complete_topo(self, text, line, begidx, endidx):
+        """Complete topo command
+
+        If no token given, return 'term' and 'http'.
+        On the other hand, complete 'term' or 'http' if token starts
+        from it, or complete file name if is one of supported formats.
+        """
+
+        terms = ['term', 'http']
+        # Supported formats
+        img_exts = ['jpg', 'png', 'bmp']
+        txt_exts = ['dot', 'yml', 'js']
+
+        # Number of given tokens is expected as two. First one is
+        # 'topo'. If it is three or more, this methods returns nothing.
+        tokens = re.sub(r"\s+", " ", line).split(' ')
+        if (len(tokens) == 2):
+            if (text == ''):
+                completions = terms
+            else:
+                completions = []
+                # Check if 2nd token is a part of terms.
+                for t in terms:
+                    if t.startswith(tokens[1]):
+                        completions.append(t)
+                # Not a part of terms, so check for completion for
+                # output file name.
+                if len(completions) == 0:
+                    if tokens[1].endswith('.'):
+                        completions = img_exts + txt_exts
+                    elif ('.' in tokens[1]):
+                        fname = tokens[1].split('.')[0]
+                        token = tokens[1].split('.')[-1]
+                        for ext in img_exts:
+                            if ext.startswith(token):
+                                completions.append(fname + '.' + ext)
+                        for ext in txt_exts:
+                            if ext.startswith(token):
+                                completions.append(fname + '.' + ext)
+            return completions
+        else:  # do nothing for three or more tokens
+            pass
 
     def do_load_cmd(self, args):
         """Load command plugin
-- 
2.13.1

  parent reply	other threads:[~2018-03-06 10:51 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-06 10:50 [spp] [PATCH 00/13] Change structure of SPP controller ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 01/13] spp: move controller to sub directory ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 02/13] controller: move connection threads ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 03/13] controller: aggregate logger to spp_common.py ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 04/13] controller: add load command ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 05/13] controller: move common methods to shell_lib ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 06/13] controller: add filter for py to compl_common ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 07/13] controller: refactor shell.py ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 08/13] controller: change logger output to logfile ogawa.yasufumi
2018-03-06 10:50 ` ogawa.yasufumi [this message]
2018-03-06 10:50 ` [spp] [PATCH 10/13] controller: add topo.py ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 11/13] controller: add topo_subgraph command ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 12/13] controller: add cat and less command ogawa.yasufumi
2018-03-06 10:50 ` [spp] [PATCH 13/13] controller: create log directory ogawa.yasufumi
2018-03-27 23:41 ` [spp] [PATCH 00/13] Change structure of SPP controller Ferruh Yigit

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=20180306105055.65210-10-ogawa.yasufumi@lab.ntt.co.jp \
    --to=ogawa.yasufumi@lab.ntt.co.jp \
    --cc=ferruh.yigit@intel.com \
    --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).