diff --git a/src/confcom/HISTORY.rst b/src/confcom/HISTORY.rst index e813e3ad208..f45806e4666 100644 --- a/src/confcom/HISTORY.rst +++ b/src/confcom/HISTORY.rst @@ -3,9 +3,9 @@ Release History =============== -1.2.8 +1.3.0 ++++++ -* Made the default minimum SVN of the infrastructure fragment 4 +* Add a new --enable-stdio flag, with a warning if neither this or --disable-stdio is set 1.2.7 ++++++ diff --git a/src/confcom/azext_confcom/_params.py b/src/confcom/azext_confcom/_params.py index 855973176ac..08bf87e28fc 100644 --- a/src/confcom/azext_confcom/_params.py +++ b/src/confcom/azext_confcom/_params.py @@ -23,6 +23,7 @@ validate_fragment_json, validate_fragment_json_policy, validate_image_target, + validate_stdio, validate_upload_fragment, validate_infrastructure_svn, ) @@ -105,9 +106,15 @@ def load_arguments(self, _): ) c.argument( "disable_stdio", - options_list=("--disable-stdio",), - required=False, + action="store_true", help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, + ) + c.argument( + "enable_stdio", + action="store_true", + help="Enable the standard io streams to leave the container", + validator=validate_stdio, ) c.argument( "diff", @@ -290,9 +297,15 @@ def load_arguments(self, _): ) c.argument( "disable_stdio", - options_list=("--disable-stdio",), - required=False, + action="store_true", help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, + ) + c.argument( + "enable_stdio", + action="store_true", + help="Enable the standard io streams to leave the container", + validator=validate_stdio, ) c.argument( "debug_mode", diff --git a/src/confcom/azext_confcom/_validators.py b/src/confcom/azext_confcom/_validators.py index d79a630bb6b..be669f70d8d 100644 --- a/src/confcom/azext_confcom/_validators.py +++ b/src/confcom/azext_confcom/_validators.py @@ -4,9 +4,13 @@ # -------------------------------------------------------------------------------------------- from knack.util import CLIError +from knack.log import get_logger from azext_confcom.config import RESERVED_FRAGMENT_NAMES, SUPPORTED_ALGOS +logger = get_logger(__name__) + + def validate_params_file(namespace): if namespace.arm_template_parameters and not namespace.arm_template: raise CLIError( @@ -131,3 +135,27 @@ def validate_fragment_path(namespace): def validate_fragment_json(namespace): if namespace.fragments_json and not namespace.generate_import: raise CLIError("Must provide --fragment-path to place a fragment import into a file") + + +def validate_stdio(namespace): + if namespace.enable_stdio and namespace.disable_stdio: + raise CLIError('Use only one of --enable-stdio or --disable-stdio.') + + +def resolve_stdio(enable_stdio_flag, disable_stdio_flag, default=True): + + stdio_enabled = default + if enable_stdio_flag is None and disable_stdio_flag is None: + logger.warning( + "WARNING: Using default stdio setting (Enabled)\n" + "For the most secure deployments, ensure stdio is disabled. " + "Default behaviour may change in the future, you can set stdio with:\n" + " --disable-stdio\n" + " --enable-stdio\n" + ) + elif enable_stdio_flag is not None: + stdio_enabled = enable_stdio_flag + elif disable_stdio_flag is not None: + stdio_enabled = not disable_stdio_flag + + return stdio_enabled diff --git a/src/confcom/azext_confcom/custom.py b/src/confcom/azext_confcom/custom.py index 4405fefcc14..acd513f2038 100644 --- a/src/confcom/azext_confcom/custom.py +++ b/src/confcom/azext_confcom/custom.py @@ -5,8 +5,10 @@ import os import sys +from typing import Optional from azext_confcom import oras_proxy, os_util, security_policy +from azext_confcom._validators import resolve_stdio from azext_confcom.config import ( DEFAULT_REGO_FRAGMENTS, POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS, REGO_IMPORT_FILE_STRUCTURE) @@ -43,7 +45,8 @@ def acipolicygen_confcom( save_to_file: str = None, debug_mode: bool = False, print_policy_to_terminal: bool = False, - disable_stdio: bool = False, + disable_stdio: Optional[bool] = None, + enable_stdio: Optional[bool] = None, print_existing_policy: bool = False, faster_hashing: bool = False, omit_id: bool = False, @@ -61,6 +64,8 @@ def acipolicygen_confcom( "For additional information, see http://aka.ms/clisecrets. \n", ) + stdio_enabled = resolve_stdio(enable_stdio, disable_stdio) + if print_existing_policy and arm_template: print_existing_policy_from_arm_template(arm_template, arm_template_parameters) return @@ -112,7 +117,7 @@ def acipolicygen_confcom( input_path, debug_mode=debug_mode, infrastructure_svn=infrastructure_svn, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), exclude_default_fragments=exclude_default_fragments, ) elif arm_template: @@ -121,7 +126,7 @@ def acipolicygen_confcom( arm_template, arm_template_parameters, debug_mode=debug_mode, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), approve_wildcards=approve_wildcards, diff_mode=diff, rego_imports=fragments_list, @@ -129,13 +134,13 @@ def acipolicygen_confcom( ) elif image_name: container_group_policies = security_policy.load_policy_from_image_name( - image_name, debug_mode=debug_mode, disable_stdio=disable_stdio + image_name, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) elif virtual_node_yaml_path: container_group_policies = security_policy.load_policy_from_virtual_node_yaml_file( virtual_node_yaml_path=virtual_node_yaml_path, debug_mode=debug_mode, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), approve_wildcards=approve_wildcards, diff_mode=diff, rego_imports=fragments_list, @@ -227,7 +232,8 @@ def acifragmentgen_confcom( fragment_path: str = None, omit_id: bool = False, generate_import: bool = False, - disable_stdio: bool = False, + disable_stdio: Optional[bool] = None, + enable_stdio: Optional[bool] = None, debug_mode: bool = False, output_filename: str = "", outraw: bool = False, @@ -235,6 +241,9 @@ def acifragmentgen_confcom( no_print: bool = False, fragments_json: str = "", ): + + stdio_enabled = resolve_stdio(enable_stdio, disable_stdio) + output_type = get_fragment_output_type(outraw) if generate_import: @@ -288,14 +297,14 @@ def acifragmentgen_confcom( if image_name: policy = security_policy.load_policy_from_image_name( - image_name, debug_mode=debug_mode, disable_stdio=disable_stdio + image_name, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) else: # this is using --input if not tar_mapping: tar_mapping = os_util.load_tar_mapping_from_config_file(input_path) policy = security_policy.load_policy_from_json_file( - input_path, debug_mode=debug_mode, disable_stdio=disable_stdio + input_path, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) # get all of the fragments that are being used in the policy # and associate them with each container group diff --git a/src/confcom/setup.py b/src/confcom/setup.py index 954d44b1874..df6c58e0180 100644 --- a/src/confcom/setup.py +++ b/src/confcom/setup.py @@ -19,7 +19,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") -VERSION = "1.2.8" +VERSION = "1.3.0" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers