diff --git a/CLI/actioner/sonic_cli_if.py b/CLI/actioner/sonic_cli_if.py
index 46a0a6b33d..dffb8d4796 100644
--- a/CLI/actioner/sonic_cli_if.py
+++ b/CLI/actioner/sonic_cli_if.py
@@ -21,7 +21,8 @@
from rpipe_utils import pipestr
import cli_client as cc
from netaddr import *
-from scripts.render_cli import show_cli_output
+from scripts.render_cli import show_cli_output, show_cli_rendered_output
+import os
import syslog
import traceback
from natsort import natsorted
@@ -2104,6 +2105,18 @@ def invoke_api(func, args=[]):
show_args.append(view_key_str)
sonic_cli_show_config.run("show_view", show_args)
return
+ elif func == "showrun_if_range":
+ if not args[0] in [ 'configure-if', 'configure-lag', 'configure-vlan' ]:
+ return
+ iflistStr = args[1].split("=")[1]
+ iflist = iflistStr.rstrip().split(",")
+ viewid = 'views=' + args[0]
+ showrun_list = []
+ for intf in iflist:
+ showrun_list.append(('show_view', viewid, 'view_keys="name={}"'.format(intf)))
+ rcfgall = sonic_cli_show_config.showconfig_views_to_buffer(showrun_list)
+ show_cli_rendered_output(rcfgall)
+ return
return api.cli_not_implemented(func)
@@ -2274,7 +2287,7 @@ def run(func, args):
elif func == "get_sonic_port_table":
show_cli_output(args[0], response)
return
- elif func == "showrun":
+ elif func == "showrun" or func == "showrun_if_range":
return
if response.ok():
diff --git a/CLI/actioner/sonic_cli_show_config.py b/CLI/actioner/sonic_cli_show_config.py
index 82712c03b5..d852219861 100644
--- a/CLI/actioner/sonic_cli_show_config.py
+++ b/CLI/actioner/sonic_cli_show_config.py
@@ -1017,9 +1017,14 @@ def parse_command_line(command_line):
cli_view.view_cmd_list.append(command_line)
-def render_cli_config(view_name="", view_keys={}):
+def render_cli_config(view_name="", view_keys={}, cacheAllKeys=False):
global CMDS_STRING, CMDS_VIEW, CMDS_VIEW_CHANGED, CMDS_SAVE_BUFFER
- context = {"view_name": view_name, "view_keys": view_keys}
+
+ if cacheAllKeys:
+ # force DB_cache to get all table keys
+ context = {"view_name": view_name, "view_keys": None}
+ else:
+ context = {"view_name": view_name, "view_keys": view_keys}
# Call application
# set cache
@@ -1027,6 +1032,8 @@ def render_cli_config(view_name="", view_keys={}):
if view_name:
for module_cb in module_startup_cb.get(view_name, []):
mod_name = inspect.getmodule(module_cb).__name__
+ if cacheAllKeys and DB_Cache.get(mod_name) != None:
+ continue
DB_Cache[mod_name] = {}
module_cb(context, DB_Cache[mod_name])
@@ -1098,7 +1105,7 @@ def read_cli_format_file(format_file):
parse_command_line(command)
-def show_views(func, args=[]):
+def show_views(func, args=[], cacheAllKeys=False):
showrun_log(logging.DEBUG, "args {}", args)
@@ -1137,7 +1144,7 @@ def show_views(func, args=[]):
showrun_log(logging.DEBUG, "view-keys {}", viewKV)
for view_name in views:
- if render_cli_config(view_name, viewKV):
+ if render_cli_config(view_name, viewKV, cacheAllKeys=cacheAllKeys):
# write() returns True if terminated
break
@@ -1161,8 +1168,27 @@ def showconfig_views_to_buffer(viewlist):
if not viewlist:
render_cli_config()
else:
+ # check repeating (ie. roughly first 5) show_view for the same viewid
+ # (used by show config within interface ranges with different keys)
+ # If repeating, force DB_cache to get all table keys once and use this
+ # cache to read each key, and not do multiple separate key fetches from DB.
+ sameviewid = False
+ viewid0 = viewlist[0][1]
+ vcnt = 0
+ for to_show in viewlist:
+ if 'show_view' == to_show[0] and viewid0 == to_show[1]:
+ vcnt += 1
+ if vcnt > 5:
+ sameviewid = True
+ break
+ else:
+ break
for to_show in viewlist:
- show_views(to_show[0], to_show[1:])
+ if sameviewid and (('show_view' != to_show[0]) or
+ (viewid0 != to_show[1])):
+ # if nolonger same viewid (it changes) then turn off
+ sameviewid = False
+ show_views(to_show[0], to_show[1:], cacheAllKeys=sameviewid)
output = CMDS_SAVE_BUFFER
diff --git a/CLI/actioner/sonic_cli_vrf.py b/CLI/actioner/sonic_cli_vrf.py
index b0bd8fd595..b98215fb95 100644
--- a/CLI/actioner/sonic_cli_vrf.py
+++ b/CLI/actioner/sonic_cli_vrf.py
@@ -22,7 +22,7 @@
import os
from rpipe_utils import pipestr
import cli_client as cc
-from scripts.render_cli import show_cli_output, write
+from scripts.render_cli import show_cli_output, show_cli_rendered_output
from sonic_cli_show_config import showconfig_views_to_buffer
import sonic_intf_utils as ifutils
import collections
@@ -430,10 +430,7 @@ def run(func, args):
gotSep = False
else:
vrfcfgs += "\n" + cfgl
- full_cmd = os.getenv("USER_COMMAND", None)
- if full_cmd is not None:
- pipestr().write(full_cmd.split())
- write(vrfcfgs.replace("\t", "\n"))
+ show_cli_rendered_output(vrfcfgs.replace("\t", "\n"))
else:
api_response = invoke_api(func, args)
diff --git a/CLI/clitree/cli-xml/interface.xml b/CLI/clitree/cli-xml/interface.xml
index 9acbeac95d..8360b007cb 100644
--- a/CLI/clitree/cli-xml/interface.xml
+++ b/CLI/clitree/cli-xml/interface.xml
@@ -2270,6 +2270,7 @@ limitations under the License.
+
@@ -2310,6 +2311,7 @@ limitations under the License.
+
@@ -2332,6 +2334,7 @@ limitations under the License.
+
+
+
+ sonic_cli_if showrun_if_range configure-arg2 iflist=arg1
+
+
+
diff --git a/CLI/renderer/scripts/render_cli.py b/CLI/renderer/scripts/render_cli.py
index 2ac0332d08..ef471df37d 100755
--- a/CLI/renderer/scripts/render_cli.py
+++ b/CLI/renderer/scripts/render_cli.py
@@ -261,6 +261,20 @@ def datetimeformat_ticks(timestring):
return ret
+def show_cli_rendered_output(output_str, continuation=False, trim=True):
+ # Show already rendered output string (no jinja2).
+ if output_str is None:
+ return 0
+
+ full_cmd = os.getenv("USER_COMMAND", None)
+ if full_cmd is not None:
+ pipestr().write(full_cmd.split())
+
+ ret = write(output_str, continuation=continuation, trim=trim)
+ sys.stdout.flush()
+ return ret
+
+
def register_custom_filters(jinja2_env, filters):
if jinja2_env is not None:
# Add generic custom filters