Source code for pod_porter.pod_porter_cli

"""
CLI for pod_porter
"""

import json
from pathlib import Path
from argparse import ArgumentParser
from importlib.metadata import version

from yaml import safe_load
from pod_porter.pod_porter import PorterMapsRunner, validate_json_against_schema
from pod_porter.util.file_read_write import write_file, create_tar_gz_file, extract_tar_gz_file, create_new_map


[docs] def common_sub_parser_map_arguments(sub_arg_parser: ArgumentParser) -> None: """Add common arguments to a sub parser :type sub_arg_parser: ArgumentParser :param sub_arg_parser: The sub parser to add the arguments to :rtype: None :returns: Nothing it appends the arguments to the sub parser """ sub_arg_parser.add_argument("-m", "--map", required=True, help="Path to the map")
[docs] def common_sub_parser_arguments(sub_arg_parser: ArgumentParser) -> None: """Add common arguments to a sub parser :type sub_arg_parser: ArgumentParser :param sub_arg_parser: The sub parser to add the arguments to :rtype: None :returns: Nothing it appends the arguments to the sub parser """ sub_arg_parser.add_argument("-n", "--name", required=True, help="Release name") common_sub_parser_map_arguments(sub_arg_parser=sub_arg_parser) sub_arg_parser.add_argument( "-f", "--file-values", required=False, default=None, help="Path to the values you want to use instead of the map values", )
[docs] def common_sub_parser_output_path(sub_arg_parser: ArgumentParser) -> None: """Add common arguments to a sub parser :type sub_arg_parser: ArgumentParser :param sub_arg_parser: The sub parser to add the arguments to :rtype: None :returns: Nothing it appends the arguments to the sub parser """ sub_arg_parser.add_argument("-o", "--output", required=True, help="Path to output file/files")
[docs] def cli_argument_parser() -> ArgumentParser: """Function to create the argument parser :rtype: ArgumentParser :returns: The argument parser """ arg_parser = ArgumentParser(description=f"pod-porter version: {version('pod-porter')}") subparsers = arg_parser.add_subparsers( title="commands", description="Valid commands: a single command is required", help="CLI Help", dest="a single command please see the -h option", ) subparsers.required = True # This is the sub parser to print the rendered compose file arg_parser_template = subparsers.add_parser("template", help="View the rendered compose file") arg_parser_template.set_defaults(which_sub="template") common_sub_parser_arguments(sub_arg_parser=arg_parser_template) # This is the sub parser to write the rendered compose file arg_parser_template_write = subparsers.add_parser("write", help="Write the rendered compose file") arg_parser_template_write.set_defaults(which_sub="template_write") common_sub_parser_arguments(sub_arg_parser=arg_parser_template_write) common_sub_parser_output_path(sub_arg_parser=arg_parser_template_write) # This is the sub parser to package the map arg_parser_map_package = subparsers.add_parser("package", help="Package the map (tar.gz) the map") arg_parser_map_package.set_defaults(which_sub="package") common_sub_parser_map_arguments(sub_arg_parser=arg_parser_map_package) common_sub_parser_output_path(sub_arg_parser=arg_parser_map_package) # This is the sub parser to un-package the map arg_parser_map_unpackage = subparsers.add_parser("un-package", help="Un-Package the map extract (tar.gz)") arg_parser_map_unpackage.set_defaults(which_sub="un-package") common_sub_parser_map_arguments(sub_arg_parser=arg_parser_map_unpackage) common_sub_parser_output_path(sub_arg_parser=arg_parser_map_unpackage) # This is the sub parser to create a new map arg_parser_map_create = subparsers.add_parser("create", help="Create a new map, with some examples") arg_parser_map_create.set_defaults(which_sub="create") common_sub_parser_map_arguments(sub_arg_parser=arg_parser_map_create) # This is the sub parser to validate a compose file arg_parser_validate_compose = subparsers.add_parser("validate-compose", help="Validate a compose file") arg_parser_validate_compose.set_defaults(which_sub="validate-compose") arg_parser_validate_compose.add_argument("-f", "--file", required=True, help="Path to the compose file") # This is the sub parser to validate values file against schema arg_parser_validate_values = subparsers.add_parser( "validate-values", help="Validate a values file against a schema" ) arg_parser_validate_values.set_defaults(which_sub="validate-values") arg_parser_validate_values.add_argument("-f", "--file", required=True, help="Path to the values file") arg_parser_validate_values.add_argument("-s", "--schema", required=True, help="Path to the values-schema.json") return arg_parser
[docs] def cli() -> None: # pragma: no cover # pylint: disable=too-many-branches,too-many-statements """Function to run the command line :rtype: None :returns: Nothing it is the CLI """ arg_parser = None try: arg_parser = cli_argument_parser() args = arg_parser.parse_args() if args.which_sub == "template": obj = PorterMapsRunner(path=args.map, release_name=args.name, values_override=args.file_values) print(obj.render_compose()) if args.which_sub == "template_write": obj = PorterMapsRunner(path=args.map, release_name=args.name, values_override=args.file_values) map_name = obj.get_map_data().name map_version = obj.get_map_data().version file_name = f"{args.name}-{map_name}-{map_version}.yaml" write_file(path=args.output, file_name=file_name, data=obj.render_compose()) if args.which_sub == "package": obj = PorterMapsRunner(path=args.map) map_name = obj.get_map_data().name map_version = obj.get_map_data().version file_name = f"{map_name}-{map_version}.tar.gz" create_tar_gz_file(path=args.map, file_name=file_name, output_path=args.output) if args.which_sub == "un-package": extract_tar_gz_file(path=args.map, output_path=args.output) if args.which_sub == "create": create_new_map(map_name_and_path=args.map) if args.which_sub == "validate-compose": compose_file_path: Path = Path(args.file) if not compose_file_path.is_file(): raise FileNotFoundError(f"File not found: {compose_file_path}") data = safe_load(compose_file_path.read_text(encoding="utf-8")) try: PorterMapsRunner.validate_compose_json_schema(compose_data=data) except ValueError as error: print(error) if args.which_sub == "validate-values": values_file = Path(args.file) if not values_file.is_file(): raise FileNotFoundError(f"File not found: {values_file}") values_file_data = safe_load(values_file.read_text(encoding="utf-8")) values_schema_file = Path(args.schema) if not values_schema_file.is_file(): raise FileNotFoundError(f"File not found: {values_schema_file}") values_schema_data = json.loads(values_schema_file.read_text(encoding="utf-8")) try: validate_json_against_schema(values_data=values_file_data, json_schema=values_schema_data) except ValueError as error: print(error) except AttributeError as error: print(f"\n !!! {error} !!! \n") arg_parser.print_help() except FileNotFoundError as error: print(f"\n !!! {error} !!! \n") arg_parser.print_help() except FileExistsError as error: print(f"\n !!! {error} !!! \n") arg_parser.print_help() except Exception as error: # pylint: disable=broad-exception-caught print(f"\n !!! {error} !!! \n") arg_parser.print_help()