Source code for ecs_composex.cli

# SPDX-License-Identifier: MPL-2.0
# Copyright 2020-2022 John Mille <john@compose-x.io>

"""
Console script for ecs_composex.
"""

import argparse
import logging
import sys
import warnings

from ecs_composex.common.aws import deploy, plan
from ecs_composex.common.logging import LOG
from ecs_composex.common.settings import ComposeXSettings
from ecs_composex.common.stacks import process_stacks
from ecs_composex.compose.compose_services.service_image.docker_opts import (
    evaluate_ecr_configs,
)
from ecs_composex.ecs_composex import generate_full_template


[docs]class ArgparseHelper(argparse._HelpAction): """ Used to help print top level '--help' arguments from argparse when used with subparsers """ def __call__(self, parser, namespace, values, option_string=None): parser.print_help() print() subparsers_actions = [ action for action in parser._actions if isinstance(action, argparse._SubParsersAction) ] for subparsers_action in subparsers_actions: for choice, subparser in list(subparsers_action.choices.items()): if choice in [ cmd["name"] for cmd in ComposeXSettings.active_commands ] or choice in [ cmd["name"] for cmd in ComposeXSettings.validation_commands ]: print(f"Command '{choice}'") print(subparser.format_usage())
[docs]def main_parser(): """ Console script for ecs_composex. """ parser = argparse.ArgumentParser(add_help=False) parser.add_argument( "-h", "--help", action=ArgparseHelper, help="show this help message and exit", ) cmd_parsers = parser.add_subparsers( dest=ComposeXSettings.command_arg, help="Command to execute." ) base_command_parser = argparse.ArgumentParser(add_help=False) files_parser = argparse.ArgumentParser(add_help=False) extras_parser = argparse.ArgumentParser(add_help=False) files_parser.add_argument( "-f", "--docker-compose-file", dest=ComposeXSettings.input_file_arg, required=True, help="Path to the Docker compose file", action="append", ) files_parser.add_argument( "-d", "--output-dir", required=False, help="Output directory to write all the templates to.", type=str, dest=ComposeXSettings.output_dir_arg, default=ComposeXSettings.default_output_dir, ) base_command_parser.add_argument( "-n", "-p", "--name", help="Name of your stack / docker project", required=True, type=str, dest=ComposeXSettings.name_arg, ) base_command_parser.add_argument( "--format", help="Defines the format you want to use.", type=str, dest=ComposeXSettings.format_arg, choices=ComposeXSettings.allowed_formats, default=ComposeXSettings.default_format, ) base_command_parser.add_argument( "--region", required=False, dest=ComposeXSettings.region_arg, help="Specify the region you want to build for" "default use default region from config or environment vars", ) base_command_parser.add_argument( "--azs", dest=ComposeXSettings.zones_arg, default=[], action="append", required=False, help="List AZs you want to deploy to specifically within the region", ) base_command_parser.add_argument( "-b", "--bucket-name", type=str, required=False, help="Bucket name to upload the templates to", dest="BucketName", ) base_command_parser.add_argument( "--role-arn", dest=ComposeXSettings.arn_arg, help="Allow you to run API calls using a specific IAM role, within same or for cross-account", required=False, ) base_command_parser.add_argument( "--disable-rollback", dest="DisableRollback", help="On create/plan, disable stack automatic rollback.", required=False, action="store_true", ) extras_parser.add_argument( "--ignore-ecr-findings", dest=ComposeXSettings.ecr_arg, action="store_true", default=False, help="For services with x-ecr defined, ignores errors if any found", ) base_command_parser.add_argument( "--loglevel", type=str, help="Log level. Defaults to INFO", required=False ) parser.add_argument( "--loglevel", type=str, help="Log level. Defaults to INFO", required=False ) for command in ComposeXSettings.active_commands: cmd_parsers.add_parser( name=command["name"], help=command["help"], parents=[base_command_parser, files_parser, extras_parser], ) for command in ComposeXSettings.validation_commands: cmd_parsers.add_parser( name=command["name"], help=command["help"], parents=[files_parser] ) for command in ComposeXSettings.neutral_commands: cmd_parsers.add_parser(name=command["name"], help=command["help"]) return parser
[docs]def main(): """ Main entry point for CLI :return: status code """ parser = main_parser() if len(sys.argv) == 1: parser.print_help() sys.exit() args = parser.parse_args() if hasattr(args, "loglevel") and args.loglevel: valid_levels = [ "FATAL", "CRITICAL", "ERROR", "WARNING", "WARN", "INFO", "DEBUG", "INFO", ] if args.loglevel.upper() in valid_levels: LOG.setLevel(logging.getLevelName(args.loglevel.upper())) LOG.handlers[0].setLevel(logging.getLevelName(args.loglevel.upper())) else: print( f"Log level value {args.loglevel} is invalid. Must me one of {valid_levels}" ) LOG.debug(args) settings = ComposeXSettings(**vars(args)) settings.set_bucket_name_from_account_id() LOG.debug(settings) if settings.deploy and not settings.upload: LOG.warning( "You must update the templates in order to deploy. We won't be deploying." ) settings.deploy = False scan_results = evaluate_ecr_configs(settings) if scan_results: return scan_results root_stack = generate_full_template(settings) process_stacks(root_stack, settings) if settings.deploy: deploy(settings, root_stack) elif settings.plan: plan(settings, root_stack) return 0
if __name__ == "__main__": sys.exit(main()) # pragma: no cover