From 243f7ebf6a07fa54cbd5db6bf7f67fee04e4f14c Mon Sep 17 00:00:00 2001 From: Martin Babinsky Date: Thu, 22 Jun 2017 13:20:05 +0200 Subject: [PATCH] delegate the indentation handling in advises to dedicated class Indentation levels are now handled transparently by a dedicated class and should not pollute the statement printing logic. https://pagure.io/freeipa/issue/7036 Reviewed-By: Florence Blanc-Renaud Reviewed-By: Alexander Bokovoy --- ipaserver/advise/base.py | 106 +++++++++++++++++++--------- ipaserver/advise/plugins/smart_card_auth.py | 45 ++++++------ 2 files changed, 93 insertions(+), 58 deletions(-) diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py index 639fd1807f72f11f46136999c4ce4c6eec6b3698..c320b002c83198cbb0fd73a5c158df07dd309242 100644 --- a/ipaserver/advise/base.py +++ b/ipaserver/advise/base.py @@ -19,6 +19,7 @@ from __future__ import print_function +from contextlib import contextmanager import os from textwrap import wrap @@ -75,6 +76,8 @@ As a result, you can redirect the advice's output directly to a script file. # ./script.sh """ +DEFAULT_INDENTATION_INCREMENT = 2 + class _IndentationTracker(object): """ @@ -131,39 +134,77 @@ class _AdviceOutput(object): self.content = [] self.prefix = '# ' self.options = None + self._indentation_tracker = _IndentationTracker( + spaces_per_indent=DEFAULT_INDENTATION_INCREMENT) + + def indent(self): + """ + Indent the statements by one level + """ + self._indentation_tracker.indent() + + def dedent(self): + """ + Dedent the statements by one level + """ + self._indentation_tracker.dedent() + + @contextmanager + def indented_block(self): + self.indent() + try: + yield + finally: + self.dedent() def comment(self, line, wrapped=True): if wrapped: - for wrapped_line in wrap(line, 70): - self.content.append(self.prefix + wrapped_line) + self.append_wrapped_and_indented_comment(line) else: - self.content.append(self.prefix + line) + self.append_comment(line) + + def append_wrapped_and_indented_comment(self, line, character_limit=70): + """ + append wrapped and indented comment to the output + """ + for wrapped_indented_line in wrap( + self.indent_statement(line), character_limit): + self.append_comment(wrapped_indented_line) + + def append_comment(self, line): + self.append_statement(self.prefix + line) + + def append_statement(self, statement): + """ + Append a line to the generated content indenting it by tracked number + of spaces + """ + self.content.append(self.indent_statement(statement)) + + def indent_statement(self, statement): + return '{indent}{statement}'.format( + indent=self._indentation_tracker.indentation_string, + statement=statement) def debug(self, line): if self.options.verbose: self.comment('DEBUG: ' + line) - def command(self, line, indent_spaces=0): - self.content.append( - '{}{}'.format(self._format_indent(indent_spaces), line)) - - def _format_indent(self, num_spaces): - return ' ' * num_spaces + def command(self, line): + self.append_statement(line) - def echo_error(self, error_message, indent_spaces=0): - self.command( - self._format_error(error_message), indent_spaces=indent_spaces) + def echo_error(self, error_message): + self.command(self._format_error(error_message)) def _format_error(self, error_message): return 'echo "{}" >&2'.format(error_message) def exit_on_failed_command(self, command_to_run, - error_message_lines, indent_spaces=0): - self.command(command_to_run, indent_spaces=indent_spaces) + error_message_lines): + self.command(command_to_run) self.exit_on_predicate( '[ "$?" -ne "0" ]', - error_message_lines, - indent_spaces=indent_spaces) + error_message_lines) def exit_on_nonroot_euid(self): self.exit_on_predicate( @@ -171,8 +212,7 @@ class _AdviceOutput(object): ["This script has to be run as root user"] ) - def exit_on_predicate(self, predicate, error_message_lines, - indent_spaces=0): + def exit_on_predicate(self, predicate, error_message_lines): commands_to_run = [ self._format_error(error_message_line) for error_message_line in error_message_lines] @@ -180,30 +220,26 @@ class _AdviceOutput(object): commands_to_run.append('exit 1') self.commands_on_predicate( predicate, - commands_to_run, - indent_spaces=indent_spaces) + commands_to_run) def commands_on_predicate(self, predicate, commands_to_run_when_true, - commands_to_run_when_false=None, - indent_spaces=0): + commands_to_run_when_false=None): if_command = 'if {}'.format(predicate) - self.command(if_command, indent_spaces=indent_spaces) - self.command('then', indent_spaces=indent_spaces) - - indented_block_spaces = indent_spaces + 2 + self.command(if_command) + self.command('then') - for command_to_run_when_true in commands_to_run_when_true: - self.command( - command_to_run_when_true, indent_spaces=indented_block_spaces) + with self.indented_block(): + for command_to_run_when_true in commands_to_run_when_true: + self.command( + command_to_run_when_true) if commands_to_run_when_false is not None: - self.command("else", indent_spaces=indent_spaces) - for command_to_run_when_false in commands_to_run_when_false: - self.command( - command_to_run_when_false, - indent_spaces=indented_block_spaces) + self.command("else") + with self.indented_block(): + for command_to_run_when_false in commands_to_run_when_false: + self.command(command_to_run_when_false) - self.command('fi', indent_spaces=indent_spaces) + self.command('fi') class Advice(Plugin): diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py index 16c01204444883ed949db73b2314ba5c404124df..75efa6f854acd5f746111ea44957a538117381ae 100644 --- a/ipaserver/advise/plugins/smart_card_auth.py +++ b/ipaserver/advise/plugins/smart_card_auth.py @@ -44,13 +44,13 @@ class common_smart_card_auth_config(Advice): "for {} in ${}".format( single_ca_path_variable, ca_paths_variable)) self.log.command("do") - self.log.exit_on_predicate( - '[ ! -f "${}" ]'.format(single_ca_path_variable), - ['Invalid CA certificate filename: ${}'.format( - single_ca_path_variable), - 'Please check that the path exists and is a valid file'], - indent_spaces=2 - ) + with self.log.indented_block(): + self.log.exit_on_predicate( + '[ ! -f "${}" ]'.format(single_ca_path_variable), + ['Invalid CA certificate filename: ${}'.format( + single_ca_path_variable), + 'Please check that the path exists and is a valid file'] + ) self.log.command("done") def upload_smartcard_ca_certificates_to_systemwide_db(self): @@ -59,13 +59,13 @@ class common_smart_card_auth_config(Advice): self.single_ca_cert_variable_name, self.smart_card_ca_certs_variable_name)) self.log.command("do") - self.log.command( - 'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" ' - '-t CT,C,C'.format( - self.systemwide_nssdb, self.single_ca_cert_variable_name - ), - indent_spaces=2 - ) + with self.log.indented_block(): + self.log.command( + 'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" ' + '-t CT,C,C'.format( + self.systemwide_nssdb, self.single_ca_cert_variable_name + ), + ) self.log.command("done") def install_smart_card_signing_ca_certs(self): @@ -74,13 +74,13 @@ class common_smart_card_auth_config(Advice): self.single_ca_cert_variable_name, self.smart_card_ca_certs_variable_name)) self.log.command("do") - self.log.exit_on_failed_command( - 'ipa-cacert-manage install ${} -t CT,C,C'.format( - self.single_ca_cert_variable_name - ), - ['Failed to install external CA certificate to IPA'], - indent_spaces=2 - ) + with self.log.indented_block(): + self.log.exit_on_failed_command( + 'ipa-cacert-manage install ${} -t CT,C,C'.format( + self.single_ca_cert_variable_name + ), + ['Failed to install external CA certificate to IPA'] + ) self.log.command("done") def update_ipa_ca_certificate_store(self): @@ -221,8 +221,7 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config): self.log.command('else') self.log.exit_on_failed_command( 'ipa-pkinit-manage enable', - ['Failed to issue PKINIT certificates to local KDC'], - indent_spaces=2) + ['Failed to issue PKINIT certificates to local KDC']) self.log.command('fi') def enable_ok_to_auth_as_delegate_on_http_principal(self): -- 2.9.4