Skip to content

Commit

Permalink
Logging line number in the warning, adding a comment for the invalid …
Browse files Browse the repository at this point in the history
…command in the new_<input_file>
  • Loading branch information
Aman-Agrawal1 committed Jun 26, 2024
1 parent f871e13 commit 49973c8
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 96 deletions.
4 changes: 4 additions & 0 deletions nspepi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ The following is an example when the configuration file does not contain any dep

The `NSPEPI` tool helps in converting the deprecated commands or features to the Citrix recommended alternatives.

**Latest version:** 1.2

**NOTE:** It is recommended to always use the latest version for the conversion, you can check the version using `nspepi --version` command.

### Running the NSPEPI tool

This tool needs to be run from the command line of the shell (you should type the `shell` command on the Citrix ADC CLI).
Expand Down
4 changes: 2 additions & 2 deletions nspepi/nspepi2/check_classic_configs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright 2021-2023 Citrix Systems, Inc. All rights reserved.
# Copyright 2021-2024 Citrix Systems, Inc. All rights reserved.
# Use of this software is governed by the license terms, if any,
# which accompany or are included with this software.

Expand Down Expand Up @@ -1222,7 +1222,7 @@ def check_responder_action(self, commandParseTree):
if commandParseTree.invalid:
return [commandParseTree]
action_type = commandParseTree.positional_value(1).value.lower()
if action_type is "noop":
if action_type == "noop":
logging.warning("NOOP action type is deprecated"
" for command [{}]".format(str(commandParseTree).strip()))
return []
Expand Down
126 changes: 76 additions & 50 deletions nspepi/nspepi2/convert_cli_commands.py

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions nspepi/nspepi2/convert_cmp_cmd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright 2021-2023 Citrix Systems, Inc. All rights reserved.
# Copyright 2021-2024 Citrix Systems, Inc. All rights reserved.
# Use of this software is governed by the license terms, if any,
# which accompany or are included with this software.

Expand Down Expand Up @@ -220,14 +220,14 @@ def convert_cmp_global_bind(self, bind_cmd_tree):
bind_cmd_tree.keyword_value("state")[0].value.lower() == \
"disabled":
logging.warning((
"Following bind command is commented out because"
"Line({}): Following bind command is commented out because"
" state is disabled. If state is disabled, then command"
" is not in use. Since state parameter is not supported"
" with the advanced configuration, so if we convert this"
" config then functionality will change. If command is"
" required please take a backup because comments will"
" not be saved in ns.conf after triggering 'save ns config': {}").
format(str(bind_cmd_tree).strip())
format(str(bind_cmd_tree.lineno), str(bind_cmd_tree).strip())
)
return ["#" + str(bind_cmd_tree)]

Expand Down
86 changes: 55 additions & 31 deletions nspepi/nspepi2/convert_filter_command.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright 2021-2023 Citrix Systems, Inc. All rights reserved.
# Copyright 2021-2024 Citrix Systems, Inc. All rights reserved.
# Use of this software is governed by the license terms, if any,
# which accompany or are included with this software.

Expand Down Expand Up @@ -395,9 +395,10 @@ def convert_filter_action(self, action_parse_tree):
return []
else:
logging.error(
"Conversion of HTMLInjection variable in "
"Line({}): Conversion of HTMLInjection variable in "
"command [{}] is not supported in this tool."
"".format(str(original_cmd).strip()))
"".format(str(original_cmd.lineno), str(original_cmd).strip()))
action_parse_tree.set_invalid()
return [action_parse_tree]

else:
Expand All @@ -413,9 +414,10 @@ def convert_filter_action(self, action_parse_tree):
self._htmlInjection["action"].append(actionName)
action_parse_tree_list = [original_cmd]
logging.error(
"Conversion of HTMLInjection feature related"
"Line({}): Conversion of HTMLInjection feature related"
" command [{}] is not supported in this tool."
"".format(str(original_cmd).strip()))
"".format(str(original_cmd.lineno), str(original_cmd).strip()))
original_cmd.set_invalid()
elif (action_type == "corrupt"):
"""
Transformation for filter action of CORRUPT as actionType
Expand Down Expand Up @@ -570,8 +572,10 @@ def convert_filter_action(self, action_parse_tree):
action_parse_tree_list = [original_cmd]
self._forward["action"].append(actionName)
logging.error(
"Conversion of FORWARD action type related command"
" [{}] not supported in this tool".format(str(original_cmd).strip()))
"Line({}): Conversion of FORWARD action type related command"
" [{}] not supported in this tool"
"".format(str(original_cmd.lineno), str(original_cmd).strip()))
original_cmd.set_invalid()

else:
"""
Expand All @@ -581,9 +585,10 @@ def convert_filter_action(self, action_parse_tree):
"""
action_parse_tree_list = [original_cmd]
logging.error(
'Error in converting original command since' +
'Line({}): Error in converting original command since' +
' CLI context of filter feature is invalid: ' +
'[{}]'.format(str(original_cmd)))
'[{}]'.format(str(original_cmd.lineno), str(original_cmd)))
original_cmd.set_invalid()
return action_parse_tree_list

@common.register_for_cmd("add", "filter", "policy")
Expand Down Expand Up @@ -641,16 +646,20 @@ def convert_filter_policy(self, policy_parse_tree):
# having value as prebody or postbody Since they belong to
# html injection family
logging.error(
"Conversion of HTMLInjection feature reated command [{}]"
"not supported in this tool.".format(str(original_cmd).strip()))
"Line({}): Conversion of HTMLInjection feature reated command [{}]"
"not supported in this tool."
"".format(str(original_cmd.lineno),str(original_cmd).strip()))
self._htmlInjection["policy"].append(policyName)
original_cmd.set_invalid()
return [original_cmd]

if policy_action in self._forward["action"]:
logging.error(
"Conversion of FORWARD action type related command [{}]"
"not supported in this tool.".format(str(original_cmd).strip()))
"Line({}): Conversion of FORWARD action type related command [{}]"
"not supported in this tool."
"".format(str(original_cmd.lineno), str(original_cmd).strip()))
self._forward["policy"].append(policyName)
original_cmd.set_invalid()
return [original_cmd]

for dict_key, dict_value in self._actionTypeName.items():
Expand Down Expand Up @@ -713,8 +722,10 @@ def convert_filter_policy(self, policy_parse_tree):
""" If input policy calls the action which points to the action
for FORWARD """
logging.error(
"Conversion of FORWARD action type command [{}]"
"not supported in this tool.".format(str(original_cmd).strip()))
"Line({}): Conversion of FORWARD action type command [{}]"
"not supported in this tool."
"".format(str(original_cmd.lineno), str(original_cmd).strip()))
original_cmd.set_invalid()
return [original_cmd]

# Changing the module name to converted module name
Expand Down Expand Up @@ -779,24 +790,29 @@ def convert_filter_vserver_bindings(

if policy_name in self._forward["policy"]:
logging.error(
"Conversion of FORWARD action type related command [{}]"
"not supported in this tool.".format(str(bind_parse_tree).strip()))
"Line({}): Conversion of FORWARD action type related command [{}]"
"not supported in this tool."
"".format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip()))
bind_parse_tree.set_invalid()
return [bind_parse_tree]

if policy_name in self._htmlInjection["policy"]:
logging.error(
"Conversion of HTMLInjection feature related command [{}]"
"not supported in this tool.".format(str(bind_parse_tree).strip()))
"Line({}): Conversion of HTMLInjection feature related command [{}]"
"not supported in this tool."
"".format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip()))
bind_parse_tree.set_invalid()
return [bind_parse_tree]

vs_name = bind_parse_tree.positional_value(0).value.lower()
if cli_cmds.vserver_protocol_dict[vs_name] not in ("HTTP", "SSL"):
logging.error("Filter policy doesn't work with the non-http protocol"
logging.error("Line({}): Filter policy doesn't work with the non-http protocol"
" type vsever. And, if we bind the converted advanced"
" policy to the non-http vserver, then either the"
" config will fail or the functionality will change,"
" so please review and remove such config"
" command [{}].".format(str(bind_parse_tree).strip()))
" command [{}]."
"".format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip()))
return ['#' + str(bind_parse_tree)]
flow_type = ("RESPONSE" if (self._converted_pol_param[
policy_name][0] == "resAction") else "REQUEST")
Expand Down Expand Up @@ -833,28 +849,32 @@ def convert_filter_global_bindings(self, bind_parse_tree):
bind_parse_tree.keyword_value("state")[0].value.lower() == \
"disabled":
logging.warning((
"Following bind command is commented out because"
"Line({}): Following bind command is commented out because"
" state is disabled. If state is disabled, then command"
" is not in use. Since state parameter is not supported"
" with the advanced configuration, so if we convert this"
" config then functionality will change. If command is"
" required please take a backup because comments will"
" not be saved in ns.conf after triggering 'save ns config': {}").
format(str(bind_parse_tree).strip())
format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip())
)
return ["#" + str(bind_parse_tree)]
policy_name = bind_parse_tree.positional_value(0).value

if policy_name in self._forward["policy"]:
logging.error(
"Conversion of FORWARD action type related command [{}]"
"not supported in this tool.".format(str(bind_parse_tree).strip()))
"Line({}): Conversion of FORWARD action type related command [{}]"
"not supported in this tool."
.format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip()))
bind_parse_tree.set_invalid()
return [bind_parse_tree]

if policy_name in self._htmlInjection["policy"]:
logging.error(
"Conversion of HTMLInjection feature related command [{}]"
"not supported in this tool.".format(str(bind_parse_tree).strip()))
"Line({}): Conversion of HTMLInjection feature related command [{}]"
"not supported in this tool.".
format(str(bind_parse_tree.lineno), str(bind_parse_tree).strip()))
bind_parse_tree.set_invalid()
return [bind_parse_tree]

policy_type = common.pols_binds.policies[policy_name].policy_type
Expand All @@ -863,6 +883,7 @@ def convert_filter_global_bindings(self, bind_parse_tree):
return [orig_tree]
bind_parse_tree = CLICommand("bind", "rewrite", "global")
bind_parse_tree.original_line = str(orig_tree)
bind_parse_tree.lineno = orig_tree.lineno
policyName = CLIPositionalParameter(policy_name)
bind_parse_tree.add_positional(policyName)
if orig_tree.keyword_exists("priority"):
Expand Down Expand Up @@ -898,8 +919,10 @@ def convert_filter_htmlinjection_command(self, commandParseTree):
"""
if cli_cmds.no_conversion_collect_data:
return []
logging.error("Conversion of HTMLInjection feature"
" related command [{}] is not supported".format(str(commandParseTree).strip()))
logging.error("Line({}): Conversion of HTMLInjection feature"
" related command [{}] is not supported"
"".format(str(commandParseTree.lineno), str(commandParseTree).strip()))
commandParseTree.set_invalid()
return [commandParseTree]

@common.register_for_final_call
Expand Down Expand Up @@ -988,10 +1011,11 @@ def get_converted_cmds(self):

def return_bind_cmd_error(self, cmd):
# Return an error and partially converted commented out bind command
logging.error("In ns.conf, existing advanced feature policies's bind commands have"
logging.error("Line({}): In ns.conf, existing advanced feature policies's bind commands have"
" gotoPriorityExpression as END/USE_INVOCATION_RESULT for HTTP/S."
" Priorities and gotoPriorityExpression will need to"
" be added modified/added manually in [{}].".format(str(cmd).strip()))
" be added modified/added manually in [{}]."
.format(str(cmd.lineno), str(cmd).strip()))
bind_cmd = '#' + str(cmd)
return bind_cmd

Expand Down
9 changes: 5 additions & 4 deletions nspepi/nspepi2/convert_lb_cmd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright 2021-2023 Citrix Systems, Inc. All rights reserved.
# Copyright 2021-2024 Citrix Systems, Inc. All rights reserved.
# Use of this software is governed by the license terms, if any,
# which accompany or are included with this software.

Expand Down Expand Up @@ -140,8 +140,9 @@ def convert_lb_rule(self, add_lbvserver_parse_tree):
else:
# CONTENTS exists but not a simple expression.
# Throw error and don't convert.
logging.error(("-rule in the following command has to be "
logging.error(("Line({}): -rule in the following command has to be "
"converted manually: {}").format(
str(add_lbvserver_parse_tree.lineno),
str(add_lbvserver_parse_tree).strip()))
return [add_lbvserver_parse_tree]

Expand Down Expand Up @@ -176,15 +177,15 @@ def convert_lb_rule(self, add_lbvserver_parse_tree):
if len(removed_keywords) > 0:
removed_keywords.append("rule")
add_lbvserver_parse_tree.remove_keyword("rule")
logging.warning(("-rule classic expression results in boolean "
logging.warning(("Line({}): -rule classic expression results in boolean "
"value. The equivalent advanced expression "
"will result boolean value in string "
"format. This will result in functionality "
"change when rule is used for persistenceType"
" or lbMethod. To aviod the functionality "
"change, {} command is modified by removing "
"the following keywords: {}.").format(
str(original_tree).strip(),
str(original_tree.lineno), str(original_tree).strip(),
", ".join(removed_keywords)))
return [add_lbvserver_parse_tree]

Expand Down
33 changes: 27 additions & 6 deletions nspepi/nspepi2/nspepi_main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright 2021-2023 Citrix Systems, Inc. All rights reserved.
# Copyright 2021-2024 Citrix Systems, Inc. All rights reserved.
# Use of this software is governed by the license terms, if any,
# which accompany or are included with this software.

Expand All @@ -13,7 +13,7 @@

# Ensure that the version string conforms to PEP 440:
# https://www.python.org/dev/peps/pep-0440/
__version__ = "1.1"
__version__ = "1.2"

import argparse
import glob
Expand Down Expand Up @@ -221,21 +221,39 @@ def convert_config_file(infile, outfile, verbose):
if key in common.dispatchtable:
for m in common.dispatchtable[key]:
for output in m.method(m.obj, parsed_tree):
output_line(str(output), outfile, verbose)
if (type(output) == str):
output_line(output, outfile, verbose)
else:
if output.invalid:
output_line((str(output).strip() + convert_cli_commands.tool_error_comment), outfile, verbose)
else:
output_line(str(output), outfile, verbose)
else:
output_line(str(parsed_tree), outfile, verbose)
else:
output_line(cmd, outfile, verbose)
# call methods registered to be called at end of processing
for m in common.final_methods:
for output in m.method(m.obj):
output_line(str(output), outfile, verbose)
if (type(output) == str):
output_line(str(output), outfile, verbose)
else:
if output.invalid:
output_line(str(output).strip() + convert_cli_commands.tool_error_comment, outfile, verbose)
else:
output_line(str(output), outfile, verbose)
# analyze policy bindings for any unsupported bindings
common.pols_binds.analyze()
# Get all bind commands after reprioritizing.
config_obj = convert_cli_commands.ConvertConfig()
for output in config_obj.reprioritize_and_emit_binds():
output_line(str(output), outfile, verbose)
if (type(output) == str):
output_line(str(output), outfile, verbose)
else:
if output.invalid:
output_line(str(output).strip() + convert_cli_commands.tool_error_comment, outfile, verbose)
else:
output_line(str(output), outfile, verbose)


def main():
Expand Down Expand Up @@ -295,6 +313,7 @@ def main():
# For other options, logs will only be in warn file and not on console.
setup_logging(log_file_name, logging.WARNING, err_file_name, debug_file_name, args.verbose or args.expression is not None)
convert_cli_commands.convert_cli_init()
convert_cli_commands.tool_error_comment = " # Error in conversion in using nspepi tool, for details see the warn_" + conf_file_name + "\n"
# convert classic policy expression if given as an argument
if args.expression is not None:
convert_cli_commands.no_conversion_collect_data = False
Expand Down Expand Up @@ -331,7 +350,9 @@ def main():
os.remove(log_file_name)
else:
error_warn_msg = ".\nCheck warn_" + conf_file_name + \
" file for all warnings or errors that have been generated."
" file for all warnings or errors that have been generated." + \
"\nPlease try to convert the errors manually or reach out to " + \
"the support team for helping in conversion."
print("\nConverted config will be available in a new file new_"
+ conf_file_name + error_warn_msg)
if args.debug:
Expand Down

0 comments on commit 49973c8

Please sign in to comment.