From: ogawa.yasufumi@lab.ntt.co.jp
To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp
Subject: [spp] [PATCH 4/5] controller: refactor SppNfv class
Date: Wed, 12 Dec 2018 11:03:14 +0900 [thread overview]
Message-ID: <1544580195-9242-5-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> (raw)
In-Reply-To: <1544580195-9242-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp>
From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
* To become maintainance easier, define methods for each of sub command
which starts from `_run`.
* Add `get_ports_and_patches()` for getting both of attributes at once
to reduce the number of requests to spp-ctl.
* Add descriptions for all of methods.
* Revise names of variables and methods.
Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
src/controller/commands/nfv.py | 349 ++++++++++++++++++++++++++---------------
1 file changed, 219 insertions(+), 130 deletions(-)
diff --git a/src/controller/commands/nfv.py b/src/controller/commands/nfv.py
index 646cdc0..e6f95d0 100644
--- a/src/controller/commands/nfv.py
+++ b/src/controller/commands/nfv.py
@@ -10,14 +10,21 @@ class SppNfv(object):
SppNfv lass is intended to be used in Shell class as a delegator for
running 'nfv' command.
- 'self.command()' is called from do_nfv() and 'self.complete()' is called
- from complete_nfv() of both of which is defined in Shell.
+ 'self.command()' is called from do_nfv() and 'self.complete()' is
+ called from complete_nfv() of both of which is defined in Shell.
"""
- # All of commands and sub-commands used for validation and completion.
- NFV_CMDS = ['status', 'exit', 'forward', 'stop', 'add', 'patch', 'del']
+ # All of spp_nfv commands used for validation and completion.
+ NFV_CMDS = ['status', 'exit', 'forward', 'stop', 'add', 'patch',
+ 'del']
def __init__(self, spp_ctl_cli, sec_id, use_cache=False):
+ """Initialize SppNfv.
+
+ Turn use_cache `True` if you do not request to spp-ctl each
+ time.
+ """
+
self.spp_ctl_cli = spp_ctl_cli
self.sec_id = sec_id
self.ports = [] # registered ports
@@ -33,126 +40,22 @@ class SppNfv(object):
params = cmdline.split(' ')[1:]
if cmd == 'status':
- res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 200:
- self.print_nfv_status(res.json())
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_status()
elif cmd == 'add':
- if self.use_cache is False:
- self.ports = self.get_registered_ports()
-
- if params[0] in self.ports:
- print("'%s' is already added." % params[0])
- else:
- if self.use_cache is True:
- self.ports.append(params[0])
-
- req_params = {'action': 'add', 'port': params[0]}
-
- res = self.spp_ctl_cli.put('nfvs/%d/ports' %
- self.sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Add %s.' % params[0])
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_add(params)
elif cmd == 'del':
- if self.use_cache is False:
- self.patches = self.get_registered_patches()
-
- # Patched ports should not be deleted.
- patched_ports = []
- for pport in self.patches:
- patched_ports.append(pport['src'])
- patched_ports.append(pport['dst'])
- patched_ports = list(set(patched_ports))
-
- if params[0] in patched_ports:
- print("Cannot delete patched port '%s'." % params[0])
- else:
- if self.use_cache is True:
- if params[0] in self.ports:
- self.ports.remove(params[0])
-
- req_params = {'action': 'del', 'port': params[0]}
- res = self.spp_ctl_cli.put('nfvs/%d/ports' %
- self.sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Delete %s.' % params[0])
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_del(params)
elif cmd == 'forward' or cmd == 'stop':
- if cmd == 'forward':
- req_params = {'action': 'start'}
- elif cmd == 'stop':
- req_params = {'action': 'stop'}
- else:
- print('Unknown command. "forward" or "stop"?')
-
- res = self.spp_ctl_cli.put('nfvs/%d/forward' %
- self.sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- if cmd == 'forward':
- print('Start forwarding.')
- else:
- print('Stop forwarding.')
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_forward_or_stop(cmd)
elif cmd == 'patch':
- if params[0] == 'reset':
- res = self.spp_ctl_cli.delete('nfvs/%d/patches' % self.sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Clear all of patches.')
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
- else:
- req_params = {'src': params[0], 'dst': params[1]}
- res = self.spp_ctl_cli.put(
- 'nfvs/%d/patches' % self.sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Patch ports (%s -> %s).' % (
- params[0], params[1]))
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_patch(params)
elif cmd == 'exit':
- res = self.spp_ctl_cli.delete('nfvs/%d' % self.sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Exit nfv %d' % self.sec_id)
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
+ self._run_exit()
else:
print('Invalid command "%s".' % cmd)
@@ -167,11 +70,6 @@ class SppNfv(object):
- ports:
- phy:0 -> ring:0
- phy:1
-
- The format of the received message is JSON and ended with
- series of null character "\x00".
-
- {"client-id":1,...,"patches":[{"src":"phy:0"...},...]}'\x00..
"""
nfv_attr = json_obj
@@ -188,7 +86,9 @@ class SppNfv(object):
else:
print(' - %s -> %s' % (port, dst))
- def get_registered_ports(self):
+ def get_ports(self):
+ """Get all of ports as a list."""
+
res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
if res is not None:
error_codes = self.spp_ctl_cli.rest_common_error_codes
@@ -199,7 +99,14 @@ class SppNfv(object):
else:
print('Error: unknown response.')
- def get_registered_patches(self):
+ def get_patches(self):
+ """Get all of patched ports as a list of dicts.
+
+ Returned value is like as
+ [{'src': 'phy:0', 'dst': 'ring:0'},
+ {'src': 'ring:1', 'dst':'vhost:1'}, ...]
+ """
+
res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
if res is not None:
error_codes = self.spp_ctl_cli.rest_common_error_codes
@@ -210,6 +117,41 @@ class SppNfv(object):
else:
print('Error: unknown response.')
+ def get_ports_and_patches(self):
+ """Get all of ports and patchs at once.
+
+ This method is to execute `get_ports()` and `get_patches()` at
+ once to reduce request to spp-ctl. Returned value is a set of
+ lists. You use this method as following.
+ ports, patches = get_ports_and_patches()
+ """
+
+ res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ ports = res.json()['ports']
+ patches = res.json()['patches']
+ return ports, patches
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def get_patched_ports(self):
+ """Get all of patched ports as a list.
+
+ This method is to get a list of patched ports instead of a dict.
+ You use this method if you simply get patches without `src` and
+ `dst`.
+ """
+
+ patched_ports = []
+ for pport in self.patches:
+ patched_ports.append(pport['src'])
+ patched_ports.append(pport['dst'])
+ return list(set(patched_ports))
+
def complete(self, sec_ids, text, line, begidx, endidx):
"""Completion for spp_nfv commands.
@@ -248,6 +190,8 @@ class SppNfv(object):
print(e)
def _compl_first_tokens(self, token):
+ """Complete spp_nfv command."""
+
res = []
for kw in self.NFV_CMDS:
if kw.startswith(token):
@@ -255,6 +199,8 @@ class SppNfv(object):
return res
def _compl_add(self, sub_tokens):
+ """Complete `add` command."""
+
if len(sub_tokens) < 3:
res = []
@@ -267,21 +213,18 @@ class SppNfv(object):
return res
def _compl_del(self, sub_tokens):
+ """Complete `del` command."""
+
# Del command consists of two tokens max, for instance,
# `nfv 1; del ring:1`.
if len(sub_tokens) < 3:
res = []
if self.use_cache is False:
- self.ports = self.get_registered_ports()
- self.patches = self.get_registered_patches()
+ self.ports, self.patches = self.get_ports_and_patches()
# Patched ports should not be included in the candidate of del.
- patched_ports = []
- for pport in self.patches:
- patched_ports.append(pport['src'])
- patched_ports.append(pport['dst'])
- patched_ports = list(set(patched_ports))
+ patched_ports = self.get_patched_ports()
# Remove ports already used from candidate.
for kw in self.ports:
@@ -300,14 +243,15 @@ class SppNfv(object):
return res
def _compl_patch(self, sub_tokens):
+ """Complete `patch` command."""
+
# Patch command consists of three tokens max, for instance,
# `nfv 1; patch phy:0 ring:1`.
if len(sub_tokens) < 4:
res = []
if self.use_cache is False:
- self.ports = self.get_registered_ports()
- self.patches = self.get_registered_patches()
+ self.ports, self.patches = self.get_ports_and_patches()
# Get patched ports of src and dst to be used for completion.
src_ports = []
@@ -344,3 +288,148 @@ class SppNfv(object):
res.append(kw)
return res
+
+ def _run_status(self):
+ """Run `status` command."""
+
+ res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ self.print_nfv_status(res.json())
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def _run_add(self, params):
+ """Run `add` command."""
+
+ if len(params) == 0:
+ print('Port is required!')
+ elif params[0] in self.ports:
+ print("'%s' is already added." % params[0])
+ else:
+ if self.use_cache is False:
+ self.ports = self.get_ports()
+
+ req_params = {'action': 'add', 'port': params[0]}
+
+ res = self.spp_ctl_cli.put('nfvs/%d/ports' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ if self.use_cache is True:
+ if not (params[0] in self.ports):
+ self.ports.append(params[0])
+ print('Add %s.' % params[0])
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def _run_del(self, params):
+ """Run `del` command."""
+
+ if len(params) == 0:
+ print('Port is required!')
+ elif 'phy:' in params[0]:
+ print("Cannot delete phy port '%s'." % params[0])
+ else:
+ if self.use_cache is False:
+ self.patches = self.get_patches()
+
+ # Patched ports should not be deleted.
+ patched_ports = self.get_patched_ports()
+
+ if params[0] in patched_ports:
+ print("Cannot delete patched port '%s'." % params[0])
+ else:
+ req_params = {'action': 'del', 'port': params[0]}
+ res = self.spp_ctl_cli.put('nfvs/%d/ports' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ if self.use_cache is True:
+ if params[0] in self.ports:
+ self.ports.remove(params[0])
+ print('Delete %s.' % params[0])
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def _run_forward_or_stop(self, cmd):
+ """Run `forward` or `stop` command.
+
+ Spp-ctl accepts this two commands via single API, so this method
+ runs one of which commands by referring `cmd` param.
+ """
+
+ if cmd == 'forward':
+ req_params = {'action': 'start'}
+ elif cmd == 'stop':
+ req_params = {'action': 'stop'}
+ else:
+ print('Unknown command. "forward" or "stop"?')
+
+ res = self.spp_ctl_cli.put('nfvs/%d/forward' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ if cmd == 'forward':
+ print('Start forwarding.')
+ else:
+ print('Stop forwarding.')
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def _run_patch(self, params):
+ """Run `patch` command."""
+
+ if len(params) == 0:
+ print('Params are required!')
+ elif params[0] == 'reset':
+ res = self.spp_ctl_cli.delete('nfvs/%d/patches' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Clear all of patches.')
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+ else:
+ if len(params) < 2:
+ print('Dst port is required!')
+ else:
+ req_params = {'src': params[0], 'dst': params[1]}
+ res = self.spp_ctl_cli.put(
+ 'nfvs/%d/patches' % self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Patch ports (%s -> %s).' % (
+ params[0], params[1]))
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def _run_exit(self):
+ """Run `exit` command."""
+
+ res = self.spp_ctl_cli.delete('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Exit nfv %d' % self.sec_id)
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
--
2.7.4
next prev parent reply other threads:[~2018-12-12 2:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-12 2:03 [spp] [PATCH 0/5] update SPP CLI ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 1/5] controller: change sec command to nfv ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 2/5] controller: change to exclude used port from del ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 3/5] controller: add checking for add and del cmds ogawa.yasufumi
2018-12-12 2:03 ` ogawa.yasufumi [this message]
2018-12-12 2:03 ` [spp] [PATCH 5/5] controller: update SppBye class ogawa.yasufumi
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=1544580195-9242-5-git-send-email-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).