* [spp] [PATCH] cli: add methods to manage ports for primary
@ 2019-10-17 12:57 yasufum.o
0 siblings, 0 replies; only message in thread
From: yasufum.o @ 2019-10-17 12:57 UTC (permalink / raw)
To: spp, ferruh.yigit, yasufum.o
From: Yasufumi Ogawa <yasufum.o@gmail.com>
* Add methods for running commands, add, del and patch,
for spp_primary.
* Add methods for running forward and del commmad for
spp_primary.
* Add several TODO comments for refactoring.
Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
---
src/cli/commands/nfv.py | 4 +
src/cli/commands/pri.py | 192 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 195 insertions(+), 1 deletion(-)
diff --git a/src/cli/commands/nfv.py b/src/cli/commands/nfv.py
index 0989eba..1144eca 100644
--- a/src/cli/commands/nfv.py
+++ b/src/cli/commands/nfv.py
@@ -95,6 +95,7 @@ class SppNfv(object):
else:
print(' - {} -> {}'.format(port, dst))
+ # TODO(yasufum) change name starts with '_' as private
def get_ports(self):
"""Get all of ports as a list."""
@@ -108,6 +109,7 @@ class SppNfv(object):
else:
print('Error: unknown response.')
+ # TODO(yasufum) change name starts with '_' as private
def get_patches(self):
"""Get all of patched ports as a list of dicts.
@@ -126,6 +128,7 @@ class SppNfv(object):
else:
print('Error: unknown response.')
+ # TODO(yasufum) change name starts with '_' as private
def get_ports_and_patches(self):
"""Get all of ports and patchs at once.
@@ -147,6 +150,7 @@ class SppNfv(object):
else:
print('Error: unknown response.')
+ # TODO(yasufum) change name starts with '_' as private
def get_patched_ports(self):
"""Get all of patched ports as a list.
diff --git a/src/cli/commands/pri.py b/src/cli/commands/pri.py
index da5eca6..c711c72 100644
--- a/src/cli/commands/pri.py
+++ b/src/cli/commands/pri.py
@@ -18,11 +18,15 @@ class SppPrimary(object):
"""
# All of primary commands used for validation and completion.
- PRI_CMDS = ['status', 'launch', 'clear']
+ PRI_CMDS = ['status', 'add', 'del', 'forward', 'stop', 'patch',
+ 'launch', 'clear']
def __init__(self, spp_ctl_cli):
self.spp_ctl_cli = spp_ctl_cli
+ self.ports = [] # registered ports
+ self.patchs = []
+
# Default args for `pri; launch`, used if given cli_config is invalid
# Setup template of args for `pri; launch`
@@ -59,6 +63,18 @@ class SppPrimary(object):
else:
print('Error: unknown response.')
+ elif subcmd == 'add':
+ self._run_add(params)
+
+ elif subcmd == 'del':
+ self._run_del(params)
+
+ elif subcmd == 'forward' or cmd == 'stop':
+ self._run_forward_or_stop(cmd)
+
+ elif subcmd == 'patch':
+ self._run_patch(params)
+
elif subcmd == 'launch':
wait_time = float(cli_config['sec_wait_launch']['val'])
self._run_launch(params, wait_time)
@@ -154,6 +170,75 @@ class SppPrimary(object):
rid=rports['id'], rx=rports['rx'], tx=rports['tx'],
rx_drop=rports['rx_drop'], tx_drop=rports['tx_drop']))
+ # TODO(yasufum) make methods start with '_get' to be shared
+ # because it is similar to nfv. _get_ports(self) is changed as
+ # _get_ports(self, proc_type).
+ def _get_ports(self):
+ """Get all of ports as a list."""
+
+ res = self.spp_ctl_cli.get('primary')
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ return res.json()['ports']
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ 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('primary')
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ return res.json()['patches']
+ elif res.status_code in error_codes:
+ pass
+ 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('primary')
+ 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 _get_empty_lcores(self):
"""Get lcore usage from spp-ctl for making launch options.
@@ -442,6 +527,111 @@ class SppPrimary(object):
prekey = None
return opts_dict
+ 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:
+ self.ports = self._get_ports()
+
+ req_params = {'action': 'add', 'port': params[0]}
+
+ res = self.spp_ctl_cli.put('primary/ports', 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.')
+
+ 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:
+ 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('primary/ports', 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.')
+
+ def _run_forward_or_stop(self, cmd):
+ """Run `forward` or `stop` command."""
+
+ 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('primary/forward', 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('primary/patches')
+ 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('primary/patches',
+ 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_launch(self, params, wait_time):
"""Launch secondary process.
--
2.17.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-10-17 12:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-17 12:57 [spp] [PATCH] cli: add methods to manage ports for primary yasufum.o
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).