Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic colouring #112

Merged
merged 2 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def read(fname):
# This call to setup() does all the work
setup(
name="ansible-deployer",
version="0.0.33",
version="0.0.34",
description="Wrapper around ansible-playbook allowing configurable tasks and permissions",
long_description=README,
long_description_content_type="text/markdown",
Expand Down
38 changes: 22 additions & 16 deletions source/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@
import datetime
import errno
import pkg_resources
from ansible_deployer.modules.globalvars import SUBCOMMANDS
from ansible_deployer.modules.configs.config import Config
from ansible_deployer.modules.locking.locking import Locking
from ansible_deployer.modules.outputs.logging import Loggers
from ansible_deployer.modules.validators.validate import Validators
from ansible_deployer.modules.runners.run import Runners
from ansible_deployer.modules import misc
from ansible_deployer.modules import globalvars

def parse_options(argv):
"""Generic function to parse options for all commands, we validate if the option was allowed for
specific subcommand outside"""
parser = argparse.ArgumentParser(add_help=True)

parser.add_argument("subcommand", nargs='*', default=None, metavar="SUBCOMMAND",
help='Specify subcommand to execute. Available commands: '+str(SUBCOMMANDS))
help='Specify subcommand to execute. Available commands: '+ \
str(globalvars.SUBCOMMANDS))
parser.add_argument("--infrastructure", "-i", nargs=1, default=[None], metavar="INFRASTRUCTURE",
help='Specify infrastructure for deploy.')
parser.add_argument("--stage", "-s", nargs=1, default=[None], metavar="STAGE",
Expand Down Expand Up @@ -49,6 +50,8 @@ def parse_options(argv):
help='Setup repo outside of workdir in requested path. This option applies'
' only to infrastructures with allow_user_checkout enabled in infra'
' config!')
parser.add_argument("--no-color", default=False, action="store_true", help='Disable coloring'
'of console messages.')

arguments = parser.parse_args(argv)

Expand All @@ -57,16 +60,22 @@ def parse_options(argv):
print(f"ansible-deployer version: {version}")
sys.exit(0)

if arguments.no_color:
PRINT_FAIL = PRINT_END = ""
else:
PRINT_FAIL = globalvars.PRINT_FAIL
PRINT_END = globalvars.PRINT_END

if not arguments.subcommand:
sub_string = ", ".join(SUBCOMMANDS).strip(", ")
print(f"[CRITICAL]: First positional argument (subcommand) is required! Available commands"
f" are: {sub_string}.")
sub_string = ", ".join(globalvars.SUBCOMMANDS).strip(", ")
print(f"{PRINT_FAIL}[CRITICAL]: First positional argument (subcommand) is required!"
f" Available commands are: {sub_string}.{PRINT_END}")
sys.exit(57)

options = {}
options["subcommand"] = arguments.subcommand[0].lower()
Validators.verify_subcommand(options["subcommand"])
Validators.verify_switches(arguments.subcommand)
Validators.verify_subcommand(options["subcommand"], arguments.no_color)
Validators.verify_switches(arguments.subcommand, arguments.no_color)

options["switches"] = arguments.subcommand[1:]
options["infra"] = arguments.infrastructure[0]
Expand All @@ -79,14 +88,10 @@ def parse_options(argv):
options["syslog"] = arguments.syslog
options["limit"] = arguments.limit[0]
options["raw_output"] = arguments.raw_runner_output
if arguments.self_setup[0]:
options["self_setup"] = os.path.abspath(arguments.self_setup[0])
else:
options["self_setup"] = None
if arguments.conf_dir[0]:
options["conf_dir"] = os.path.abspath(arguments.conf_dir[0])
else:
options["conf_dir"] = None
options["self_setup"] = os.path.abspath(arguments.self_setup[0]) if arguments.self_setup[0] \
else None
options["conf_dir"] = os.path.abspath(arguments.conf_dir[0]) if arguments.conf_dir[0] else None
options["no_color"] = arguments.no_color

return options

Expand All @@ -95,7 +100,8 @@ def main():
start_ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")

if len(sys.argv) < 2:
print("[CRITICAL]: Too few arguments", file=sys.stderr)
print(f"{globalvars.PRINT_FAIL}[CRITICAL]: Too few arguments{globalvars.PRINT_END}",
file=sys.stderr)
sys.exit(2)
options = parse_options(sys.argv[1:])

Expand Down
2 changes: 2 additions & 0 deletions source/modules/globalvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
APP_CONF = "/etc/ansible-deployer"
CFG_PERMISSIONS = "0o644"
SUBCOMMANDS = ("run", "lock", "unlock", "verify", "show")
PRINT_FAIL = '\033[91m'
PRINT_END = '\033[0m'
31 changes: 29 additions & 2 deletions source/modules/outputs/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def set_logging(options: dict):
logger = logging.getLogger("ansible-deployer_log")
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s [%(levelname)s]: %(message)s")
console_formatter = logging.Formatter("\n%(asctime)s [%(levelname)s]: %(message)s\n")
console_formatter = "\n%(asctime)s [%(levelname)s]: %(message)s\n"

if options["syslog"]:
rsys_handler = log_han.SysLogHandler(address="/dev/log")
Expand All @@ -31,7 +31,8 @@ def set_logging(options: dict):
logger.addHandler(memory_handler)

console_handler = logging.StreamHandler()
console_handler.setFormatter(console_formatter)
console_handler.setFormatter(logging.Formatter(console_formatter) if options["no_color"] \
else CustomFormatter(console_formatter))
console_handler.setLevel(logging.DEBUG if options["debug"] else logging.INFO)
logger.addHandler(console_handler)

Expand All @@ -46,3 +47,29 @@ def set_logging_to_file(self, log_dir: str, timestamp: str, conf: dict):
file_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s]: %(message)s"))
file_handler.setLevel(logging.DEBUG)
self.logger.addHandler(file_handler)


class CustomFormatter(logging.Formatter):
"""Class adding colours to console logger"""

def __init__(self, formatter):
super().__init__()
grey = "\x1b[0;38m"
light_green = "\x1b[1;32m"
yellow = "\x1b[0;33m"
red = "\x1b[0;31m"
light_red = "\x1b[1;31m"
reset = "\x1b[0m"

self.FORMATS = {
logging.DEBUG: light_green + formatter + reset,
logging.INFO: grey + formatter + reset,
logging.WARNING: yellow + formatter + reset,
logging.ERROR: red + formatter + reset,
logging.CRITICAL: light_red + formatter + reset
}

def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record)
31 changes: 22 additions & 9 deletions source/modules/validators/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
import os
import re
from ansible_deployer.modules.globalvars import SUBCOMMANDS
from ansible_deployer.modules import globalvars


class Validators:
Expand All @@ -13,26 +13,39 @@ def __init__(self, logger):
self.logger = logger

@staticmethod
def verify_subcommand(command: str):
def verify_subcommand(command: str, color_flag: bool):
"""Function to check the first arguments for a valid subcommand"""
if command not in SUBCOMMANDS:
print("[CRITICAL]: Unknown subcommand :%s", (command), file=sys.stderr)
if color_flag:
PRINT_FAIL = PRINT_END = ""
else:
PRINT_FAIL = globalvars.PRINT_FAIL
PRINT_END = globalvars.PRINT_END

if command not in globalvars.SUBCOMMANDS:
print(f"{PRINT_FAIL}[CRITICAL]: Unknown subcommand :%s {PRINT_END}", (command),
file=sys.stderr)
sys.exit("55")

@staticmethod
def verify_switches(switches: list):
def verify_switches(switches: list, color_flag: bool):
"""
Check if 2nd and following positional arguments are valid
"""
if color_flag:
PRINT_FAIL = PRINT_END = ""
else:
PRINT_FAIL = globalvars.PRINT_FAIL
PRINT_END = globalvars.PRINT_END

if switches[0] != "show" and len(switches[1:]) > 0:
print("[CRITICAL]: Too many positional arguments! Only subcommand \"show\" can accept"
" following arguments: all, task, infra.")
print(f"{PRINT_FAIL}[CRITICAL]: Too many positional arguments! Only subcommand \"show\""
f" can accept following arguments: all, task, infra.{PRINT_END}")
sys.exit("56")

for switch in switches[1:]:
if switch not in ("all", "task", "infra"):
print(f"[CRITICAL]: Invalid argument {switch}! Subcommand \"show\" can accept only"
" following arguments: all, task, infra.")
print(f"{PRINT_FAIL}[CRITICAL]: Invalid argument {switch}! Subcommand \"show\" can"
f" accept only following arguments: all, task, infra.{PRINT_END}")
sys.exit("57")

def validate_options(self, options: dict):
Expand Down