From e9829363835d5bd2ad242aadf9d59b44b94a8b46 Mon Sep 17 00:00:00 2001 From: Akash Chandra Date: Mon, 27 Jan 2025 14:34:13 +0530 Subject: [PATCH] feat: enable show udf to print content --- lib/live_cluster/client/node.py | 15 +++++++++++ lib/live_cluster/get_controller.py | 4 ++- lib/live_cluster/show_controller.py | 42 ++++++++++++++++++++++++----- lib/view/view.py | 25 +++++++++++++++++ 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/lib/live_cluster/client/node.py b/lib/live_cluster/client/node.py index 984a9bbd..fabfda36 100644 --- a/lib/live_cluster/client/node.py +++ b/lib/live_cluster/client/node.py @@ -2247,6 +2247,21 @@ async def info_udf_list(self): return client_util.info_to_dict_multi_level( udf_data, "filename", delimiter2="," ) + + @async_return_exceptions + async def info_udf_get(self, filename): + """ + Get list of UDFs stored on the node. + + Returns: + dict -- {: {"content": , "type": 'LUA'}, . . .} + """ + udf_data = await self._info("udf-get:filename={}".format(filename)) + + if not udf_data: + return {} + + return client_util.info_to_dict(udf_data) @async_return_exceptions async def info_udf_put(self, udf_file_name, udf_str, udf_type="LUA"): diff --git a/lib/live_cluster/get_controller.py b/lib/live_cluster/get_controller.py index 0b9ff3b1..012ba43e 100644 --- a/lib/live_cluster/get_controller.py +++ b/lib/live_cluster/get_controller.py @@ -1090,7 +1090,9 @@ def __init__(self, cluster): async def get_udfs(self, nodes="all"): return await self.cluster.info_udf_list(nodes=nodes) - + + async def get_udf_content(self, nodes="all", filename=None): + return await self.cluster.info_udf_get(nodes=nodes, filename=filename) class GetSIndexController: def __init__(self, cluster): diff --git a/lib/live_cluster/show_controller.py b/lib/live_cluster/show_controller.py index 9da4e7bd..4d40f1be 100644 --- a/lib/live_cluster/show_controller.py +++ b/lib/live_cluster/show_controller.py @@ -1587,20 +1587,48 @@ async def _do_default(self, line): "Displays UDF modules along with metadata.", modifiers=( ModifierHelp(Modifiers.LIKE, "Filter UDFs by name using a substring match"), + ModifierHelp( + "--name", + "Show UDF by exact name match", + ), + ModifierHelp( + "-n", + "Show UDF by exact name match", + ), ), - usage=f"[{ModifierUsage.LIKE}]", + usage=f"[{ModifierUsage.LIKE}] [--name ] [-n ]", ) class ShowUdfsController(LiveClusterCommandController): def __init__(self): - self.modifiers = set([Modifiers.LIKE]) + self.modifiers = set([Modifiers.LIKE, '-v', '--name', '-n']) self.getter = GetUdfController(self.cluster) async def _do_default(self, line): - udfs_data = await self.getter.get_udfs(nodes="principal") - resp = list(udfs_data.values())[0] - - return self.view.show_udfs(resp, **self.mods) - + udf_name = util.get_arg_and_delete_from_mods( + line=line, + arg="--filename", + default="", + return_type=str, + modifiers=self.modifiers, + mods=self.mods, + ) or util.get_arg_and_delete_from_mods( + line=line, + arg="-f", + default="", + return_type=str, + modifiers=self.modifiers, + mods=self.mods, + ) + + if udf_name != "": + udfs_data = await self.getter.get_udf_content(nodes="principal", filename=udf_name) + resp = list(udfs_data.values())[0] + return self.view.show_udf_content(resp, udf_name, **self.mods) + else: + udfs_data = await self.getter.get_udfs(nodes="principal") + resp = list(udfs_data.values())[0] + self.view.show_udfs(resp, **self.mods) + @CommandHelp( "Displays secondary indexes and static metadata.", diff --git a/lib/view/view.py b/lib/view/view.py index 9505e53c..d0164b2f 100644 --- a/lib/view/view.py +++ b/lib/view/view.py @@ -16,6 +16,7 @@ import datetime import locale import logging +import base64 from os import path import sys import time @@ -1121,6 +1122,30 @@ def show_roles(roles_data, like=None, timestamp="", **ignore): CliView.print_result(sheet.render(templates.show_roles, title, sources)) + @staticmethod + def show_udf_content(udf_data, udf_name="", timestamp="", **ignore): + if not udf_data: + return + + if 'error' in udf_data: + CliView.print_result("Failed to find the udf {}".format(udf_name)) + return + + title_timestamp = CliView._get_timestamp_suffix(timestamp) + title = "UDF Module Content {}".format(title_timestamp) + + CliView.print_result(title) + CliView.print_result("=" * len(title)) + + + # decode the base64 encoded content + content = base64.b64decode(udf_data['content']).decode('utf-8') + radius = (max([ len(line) for line in content.split('\n') ]) + 1 ) // 2 + CliView.print_result("~" * radius + " Type:" + udf_data['type'] + " " + "~" * radius + "\n") + CliView.print_result(content) + CliView.print_result("~" * radius * 2) + + @staticmethod def show_udfs(udfs_data, like, timestamp="", **ignore): if not udfs_data: