mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
python: Add option for JSON output to unixctl classes and appctl.py.
This patch introduces support for different output formats to Python Unixctl* classes and appctl.py, similar to what the previous commit did for ovs-appctl. In particular, tests/appctl.py gains a global option '-f,--format' which allows users to request JSON instead of plain-text for humans. Reported-at: https://bugzilla.redhat.com/1824861 Signed-off-by: Jakob Meng <code@jakobmeng.de> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
committed by
Ilya Maximets
parent
939a5cea5b
commit
97a1bce6aa
@@ -12,6 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import enum
|
||||
import sys
|
||||
|
||||
import ovs.util
|
||||
@@ -19,6 +20,13 @@ import ovs.util
|
||||
commands = {}
|
||||
|
||||
|
||||
@enum.unique
|
||||
# FIXME: Use @enum.verify(enum.NAMED_FLAGS) from Python 3.11 when available.
|
||||
class UnixctlOutputFormat(enum.IntFlag):
|
||||
TEXT = 1 << 0
|
||||
JSON = 1 << 1
|
||||
|
||||
|
||||
class _UnixctlCommand(object):
|
||||
def __init__(self, usage, min_args, max_args, callback, aux):
|
||||
self.usage = usage
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
import os
|
||||
|
||||
import ovs.json
|
||||
import ovs.jsonrpc
|
||||
import ovs.stream
|
||||
import ovs.util
|
||||
@@ -41,10 +42,10 @@ class UnixctlClient(object):
|
||||
return error, None, None
|
||||
|
||||
if reply.error is not None:
|
||||
return 0, str(reply.error), None
|
||||
return 0, reply.error, None
|
||||
else:
|
||||
assert reply.result is not None
|
||||
return 0, None, str(reply.result)
|
||||
return 0, None, reply.result
|
||||
|
||||
def close(self):
|
||||
self._conn.close()
|
||||
|
@@ -12,6 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import errno
|
||||
import os
|
||||
@@ -35,6 +36,7 @@ class UnixctlConnection(object):
|
||||
assert isinstance(rpc, ovs.jsonrpc.Connection)
|
||||
self._rpc = rpc
|
||||
self._request_id = None
|
||||
self._fmt = ovs.unixctl.UnixctlOutputFormat.TEXT
|
||||
|
||||
def run(self):
|
||||
self._rpc.run()
|
||||
@@ -63,10 +65,29 @@ class UnixctlConnection(object):
|
||||
return error
|
||||
|
||||
def reply(self, body):
|
||||
self._reply_impl(True, body)
|
||||
assert body is None or isinstance(body, str)
|
||||
|
||||
if body is None:
|
||||
body = ""
|
||||
|
||||
if self._fmt == ovs.unixctl.UnixctlOutputFormat.JSON:
|
||||
body = {
|
||||
"reply-format": "plain",
|
||||
"reply": body
|
||||
}
|
||||
|
||||
return self._reply_impl_json(True, body)
|
||||
|
||||
def reply_json(self, body):
|
||||
self._reply_impl_json(True, body)
|
||||
|
||||
def reply_error(self, body):
|
||||
self._reply_impl(False, body)
|
||||
assert body is None or isinstance(body, str)
|
||||
|
||||
if body is None:
|
||||
body = ""
|
||||
|
||||
return self._reply_impl_json(False, body)
|
||||
|
||||
# Called only by unixctl classes.
|
||||
def _close(self):
|
||||
@@ -78,15 +99,11 @@ class UnixctlConnection(object):
|
||||
if not self._rpc.get_backlog():
|
||||
self._rpc.recv_wait(poller)
|
||||
|
||||
def _reply_impl(self, success, body):
|
||||
def _reply_impl_json(self, success, body):
|
||||
assert isinstance(success, bool)
|
||||
assert body is None or isinstance(body, str)
|
||||
|
||||
assert self._request_id is not None
|
||||
|
||||
if body is None:
|
||||
body = ""
|
||||
|
||||
if success:
|
||||
reply = Message.create_reply(body, self._request_id)
|
||||
else:
|
||||
@@ -133,6 +150,25 @@ def _unixctl_version(conn, unused_argv, version):
|
||||
conn.reply(version)
|
||||
|
||||
|
||||
def _unixctl_set_options(conn, argv, unused_aux):
|
||||
assert isinstance(conn, UnixctlConnection)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--format", default="text",
|
||||
choices=[fmt.name.lower()
|
||||
for fmt in ovs.unixctl.UnixctlOutputFormat],
|
||||
type=str.lower)
|
||||
|
||||
try:
|
||||
args = parser.parse_args(args=argv)
|
||||
except argparse.ArgumentError as e:
|
||||
conn.reply_error(str(e))
|
||||
return
|
||||
|
||||
conn._fmt = ovs.unixctl.UnixctlOutputFormat[args.format.upper()]
|
||||
conn.reply(None)
|
||||
|
||||
|
||||
class UnixctlServer(object):
|
||||
def __init__(self, listener):
|
||||
assert isinstance(listener, ovs.stream.PassiveStream)
|
||||
@@ -207,4 +243,7 @@ class UnixctlServer(object):
|
||||
ovs.unixctl.command_register("version", "", 0, 0, _unixctl_version,
|
||||
version)
|
||||
|
||||
ovs.unixctl.command_register("set-options", "[--format text|json]", 1,
|
||||
2, _unixctl_set_options, None)
|
||||
|
||||
return 0, UnixctlServer(listener)
|
||||
|
Reference in New Issue
Block a user