diff --git a/src/confcom/.gitignore b/src/confcom/.gitignore index d60f4d0f18a..eb7212ecef5 100644 --- a/src/confcom/.gitignore +++ b/src/confcom/.gitignore @@ -27,6 +27,8 @@ azext_confcom/bin/ azext_confcom/bin/* **/dmverity-vhd.exe **/dmverity-vhd + # metadata file for coverage reports **/.coverage -**/htmlcov \ No newline at end of file + +**/htmlcov diff --git a/src/confcom/azext_confcom/_params.py b/src/confcom/azext_confcom/_params.py index ae70721e8b0..41e8babdd61 100644 --- a/src/confcom/azext_confcom/_params.py +++ b/src/confcom/azext_confcom/_params.py @@ -89,7 +89,7 @@ def load_arguments(self, _): help="Validate that the image used to generate the CCE Policy for a sidecar container will be allowed by its generated policy", ) c.argument( - "print-existing-policy", + "print_existing_policy", options_list=("--print-existing-policy"), required=False, action="store_true", diff --git a/src/confcom/azext_confcom/config.py b/src/confcom/azext_confcom/config.py index 7f7392efe55..a9807cc236c 100644 --- a/src/confcom/azext_confcom/config.py +++ b/src/confcom/azext_confcom/config.py @@ -26,6 +26,10 @@ ACI_FIELD_CONTAINERS_WAIT_MOUNT_POINTS = "wait_mount_points" ACI_FIELD_CONTAINERS_ALLOW_ELEVATED = "allow_elevated" ACI_FIELD_CONTAINERS_SECURITY_CONTEXT = "securityContext" +ACI_FIELD_CONTAINERS_ALLOW_PRIVILEGE_ESCALATION = "allowPrivilegeEscalation" +ACI_FIELD_CONTAINERS_RUN_AS_USER = "runAsUser" +ACI_FIELD_CONTAINERS_RUN_AS_GROUP = "runAsGroup" +ACI_FIELD_CONTAINERS_SECCOMP_PROFILE = "seccompProfile" ACI_FIELD_CONTAINERS_REGO_FRAGMENTS = "fragments" ACI_FIELD_CONTAINERS_REGO_FRAGMENTS_FEED = "feed" ACI_FIELD_CONTAINERS_REGO_FRAGMENTS_ISS = "iss" @@ -63,6 +67,9 @@ ACI_FIELD_TEMPLATE_CONFCOM_PROPERTIES = "confidentialComputeProperties" ACI_FIELD_TEMPLATE_CCE_POLICY = "ccePolicy" ACI_FIELD_CONTAINERS_PRIVILEGED = "privileged" +ACI_FIELD_CONTAINERS_CAPABILITIES = "capabilities" +ACI_FIELD_CONTAINERS_CAPABILITIES_ADD = "add" +ACI_FIELD_CONTAINERS_CAPABILITIES_DROP = "drop" # output json values @@ -87,9 +94,23 @@ POLICY_FIELD_CONTAINERS_ELEMENTS_MOUNTS_OPTIONS = "options" POLICY_FIELD_CONTAINERS_ELEMENTS_WAIT_MOUNT_POINTS = "wait_mount_points" POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_ELEVATED = "allow_elevated" -POLICY_FIELD_CONTAINER_EXEC_PROCESSES = "exec_processes" -POLICY_FIELD_CONTAINER_SIGNAL_CONTAINER_PROCESSES = "signals" -POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS = "allow_stdio_access" +POLICY_FIELD_CONTAINERS_ELEMENTS_NO_NEW_PRIVILEGES = "no_new_privileges" +POLICY_FIELD_CONTAINERS_ELEMENTS_EXEC_PROCESSES = "exec_processes" +POLICY_FIELD_CONTAINERS_ELEMENTS_SIGNAL_CONTAINER_PROCESSES = "signals" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER = "user" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER_USER_IDNAME = "user_idname" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER_GROUP_IDNAMES = "group_idnames" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER_UMASK = "umask" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER_PATTERN = "pattern" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES = "capabilities" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING = "bounding" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE = "effective" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE = "inheritable" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED = "permitted" +POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT = "ambient" +POLICY_FIELD_CONTAINERS_ELEMENTS_USER_STRATEGY = "strategy" +POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256 = "seccomp_profile_sha256" +POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS = "allow_stdio_access" POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS = "fragments" POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS_FEED = "feed" POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS_ISS = "iss" @@ -135,7 +156,14 @@ SIDECAR_REGO_FILE = "./data/sidecar_rego_policy.txt" SIDECAR_REGO_FILE_PATH = f"{script_directory}/{SIDECAR_REGO_FILE}" SIDECAR_REGO_POLICY = os_util.load_str_from_file(SIDECAR_REGO_FILE_PATH) + # api version API_VERSION = _config["version_api"] # default containers to be added to all container groups DEFAULT_CONTAINERS = _config["default_containers"] +# default container user config to be added for security context +DEFAULT_USER = _config["default_user"] +# default unpriviliged user capabilities to be added for security context +DEFAULT_UNPRIVILEGED_CAPABILITIES = _config["default_unprivileged_capabilities"] +# default priviliged user capabilities to be added for security context +DEFAULT_PRIVILEGED_CAPABILITIES = _config["default_privileged_capabilities"] diff --git a/src/confcom/azext_confcom/container.py b/src/confcom/azext_confcom/container.py index 7e9de5d7235..30599524044 100644 --- a/src/confcom/azext_confcom/container.py +++ b/src/confcom/azext_confcom/container.py @@ -7,13 +7,22 @@ import json import os from typing import Any, List, Dict -from azext_confcom.template_util import case_insensitive_dict_get, replace_params_and_vars +from itertools import product +from azext_confcom.template_util import ( + case_insensitive_dict_get, + replace_params_and_vars, + str_to_sha256, + process_seccomp_policy +) from azext_confcom import config from azext_confcom.errors import eprint +from azext_confcom.os_util import base64_to_str _DEFAULT_MOUNTS = config.DEFAULT_MOUNTS_USER +_DEFAULT_USER = config.DEFAULT_USER + _INJECTED_CUSTOMER_ENV_RULES = ( config.OPENGCS_ENV_RULES + config.FABRIC_ENV_RULES @@ -21,6 +30,14 @@ + config.ENABLE_RESTART_ENV_RULE ) +_CAPABILITIES = { + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING: [], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE: [], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE: [], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED: [], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT: [], +} + def extract_container_image(container_json: Any) -> str: containerImage = case_insensitive_dict_get( @@ -207,7 +224,7 @@ def extract_exec_process(container_json: Any) -> List: exec_processes_output.append( { config.POLICY_FIELD_CONTAINERS_ELEMENTS_COMMANDS: exec_command, - config.POLICY_FIELD_CONTAINER_SIGNAL_CONTAINER_PROCESSES: exec_signals, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_SIGNAL_CONTAINER_PROCESSES: exec_signals, } ) return exec_processes_output @@ -233,24 +250,22 @@ def extract_allow_elevated(container_json: Any) -> bool: if isinstance(privileged_value, str): privileged_value = privileged_value.lower() == "true" - if privileged_value is not None: + if privileged_value: return privileged_value # allow_elevated is used for input.json _allow_elevated = case_insensitive_dict_get( container_json, config.ACI_FIELD_CONTAINERS_ALLOW_ELEVATED ) - if _allow_elevated: + if _allow_elevated is not None: if not isinstance(_allow_elevated, bool): eprint( f'Field ["{config.ACI_FIELD_CONTAINERS}"]' + f'["{config.ACI_FIELD_CONTAINERS_ALLOW_ELEVATED}"] can only be boolean value.' ) - - if _allow_elevated is not None: return _allow_elevated - # default value is true - return True + # default value is false + return False def extract_allow_stdio_access(container_json: Any) -> bool: @@ -262,6 +277,210 @@ def extract_allow_stdio_access(container_json: Any) -> bool: return allow_stdio_access +def extract_user(container_json: Any) -> Dict: + security_context = case_insensitive_dict_get( + container_json, config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT + ) + + user = copy.deepcopy(_DEFAULT_USER) + # assumes that securityContext field is optional + if security_context: + # To-Do: figure out how to determine if regex patterns + # get the field for run as user + run_as_user_value = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_RUN_AS_USER + ) + + if isinstance(run_as_user_value, int) and run_as_user_value >= 0: + user[config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_USER_IDNAME] = { + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_PATTERN: str(run_as_user_value), + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_STRATEGY: "id" + } + elif run_as_user_value is not None: + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_RUN_AS_USER}"] can only be an integer value.' + ) + + # get the field for run as group + run_as_group_value = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_RUN_AS_GROUP + ) + + if isinstance(run_as_group_value, int) and run_as_group_value >= 0: + user[config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_GROUP_IDNAMES][0] = { + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_PATTERN: str(run_as_group_value), + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_STRATEGY: "id" + } + elif run_as_group_value is not None: + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_RUN_AS_GROUP}"] can only be an integer value.' + ) + + return user + + +def extract_capabilities(container_json: Any, allow_elevated: bool): + security_context = case_insensitive_dict_get( + container_json, config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT + ) + # get the field for privileged, default to false + privileged_value = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_PRIVILEGED + ) + if privileged_value and not isinstance(privileged_value, bool) and not isinstance(privileged_value, str): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_PRIVILEGED}"] can only be a boolean or string value.' + ) + + # force the field into a bool + if isinstance(privileged_value, str): + privileged_value = privileged_value.lower() == "true" + + output_capabilities = copy.deepcopy(_CAPABILITIES) + + # if privileged and allow elevated is true, then set all capabilities to true + # else, get the capabilities field from the ARM Template + if privileged_value and allow_elevated: + for key in output_capabilities: + # we still want the ambient set to be empty + if key != config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT: + output_capabilities[key] = copy.deepcopy(config.DEFAULT_PRIVILEGED_CAPABILITIES) + else: + non_added_fields = [ + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED, + ] + + # add the default capabilities to the output + for key in non_added_fields: + output_capabilities[key] = copy.deepcopy(config.DEFAULT_UNPRIVILEGED_CAPABILITIES) + # get the capabilities field + capabilities = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_CAPABILITIES + ) + # if allow elevated is true and container is not privileged, + # user can ADD and DROP capabilities in the ARM template + # if not allow elevated and container is not privileged, use default unprivileged capabilities + if capabilities and allow_elevated: + # error check if capabilities is not a dict + if not isinstance(capabilities, dict): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_CAPABILITIES}"] can only be a dictionary.' + ) + + # get the add field + add = case_insensitive_dict_get( + capabilities, config.ACI_FIELD_CONTAINERS_CAPABILITIES_ADD + ) + if add: + # error check if add is not a list + if not isinstance(add, list): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_CAPABILITIES_ADD}"] can only be a list.' + ) + for key, capability in product(output_capabilities, add): + # error check that all the items in "add" are strings + if not isinstance(capability, str): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]' + + f'["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_CAPABILITIES_ADD}"] can only contain strings.' + ) + # add the capabilities to the output, except ambient list + # we still want the ambient set to be empty + if key != config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT: + output_capabilities[key].append(capability) + + # get the drop field + drop = case_insensitive_dict_get( + capabilities, config.ACI_FIELD_CONTAINERS_CAPABILITIES_DROP + ) + if drop: + # error check if drop is not a list + if not isinstance(drop, list): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_CAPABILITIES_DROP}"] can only be a list.' + ) + # error check that all the items in "drop" are strings + for capability in drop: + if not isinstance(capability, str): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]' + + f'["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_CAPABILITIES_DROP}"] can only contain strings.' + ) + # drop the capabilities from the output + for value in non_added_fields: + output_capabilities[value] = [x for x in output_capabilities[value] if x not in drop] + # de-duplicate the capabilities + for key, value in output_capabilities.items(): + output_capabilities[key] = sorted(list(set(value))) + return output_capabilities + + +def extract_seccomp_profile_sha256(container_json: Any) -> Dict: + security_context = case_insensitive_dict_get( + container_json, config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT + ) + + seccomp_profile_sha256 = "" + # assumes that securityContext field is optional + if security_context: + # get the field for seccomp_profile + seccomp_profile_base64 = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_SECCOMP_PROFILE + ) + + if seccomp_profile_base64 is not None and not isinstance(seccomp_profile_base64, str): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_SECCOMP_PROFILE}"] can only be a string.' + ) + elif seccomp_profile_base64 is not None: + # clean up and jsonify the seccomp profile + seccomp_profile = process_seccomp_policy(base64_to_str(seccomp_profile_base64)) + seccomp_profile_str = json.dumps(seccomp_profile, separators=(',', ':')) + # hash the seccomp profile + seccomp_profile_sha256 = str_to_sha256(seccomp_profile_str) + return seccomp_profile_sha256 + + +def extract_allow_privilege_escalation(container_json: Any) -> bool: + security_context = case_insensitive_dict_get( + container_json, config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT + ) + + # default to false so that no_new_privileges defaults to true + allow_privilege_escalation = False + # assumes that securityContext field is optional + if security_context: + + # get the field for allow privilege escalation, default to true + temp_privilege_escalation = case_insensitive_dict_get( + security_context, + config.ACI_FIELD_CONTAINERS_ALLOW_PRIVILEGE_ESCALATION + ) + if temp_privilege_escalation is not None: + if not isinstance(temp_privilege_escalation, bool) and not isinstance(temp_privilege_escalation, str): + eprint( + f'Field ["{config.ACI_FIELD_CONTAINERS}"]["{config.ACI_FIELD_CONTAINERS_SECURITY_CONTEXT}"]' + + f'["{config.ACI_FIELD_CONTAINERS_PRIVILEGED}"] can only be a boolean or string value.' + ) + + # force the field into a bool + if isinstance(temp_privilege_escalation, str): + temp_privilege_escalation = temp_privilege_escalation.lower() == "true" + allow_privilege_escalation = temp_privilege_escalation + return allow_privilege_escalation + + def extract_get_signals(container_json: Any) -> List: # get the signals info used as a liveness probe signals = ( @@ -307,7 +526,11 @@ def from_json( container_json ) signals = extract_get_signals(container_json) + user = extract_user(container_json) + capabilities = extract_capabilities(container_json, allow_elevated) + seccomp_profile_sha256 = extract_seccomp_profile_sha256(container_json) allow_stdio_access = extract_allow_stdio_access(container_json) + allow_privilege_escalation = extract_allow_privilege_escalation(container_json) return ContainerImage( containerImage=container_image, environmentRules=environment_rules, @@ -318,7 +541,11 @@ def from_json( extraEnvironmentRules=[], execProcesses=exec_processes, signals=signals, + user=user, + capabilities=capabilities, + seccomp_profile_sha256=seccomp_profile_sha256, allowStdioAccess=allow_stdio_access, + allowPrivilegeEscalation=allow_privilege_escalation, id_val=id_val, ) @@ -332,7 +559,11 @@ def __init__( allow_elevated: bool, id_val: str, extraEnvironmentRules: Dict, + capabilities: Dict = copy.deepcopy(_CAPABILITIES), + user: Dict = copy.deepcopy(_DEFAULT_USER), + seccomp_profile_sha256: str = "", allowStdioAccess: bool = True, + allowPrivilegeEscalation: bool = True, execProcesses: List = None, signals: List = None, ) -> None: @@ -348,6 +579,10 @@ def __init__( self._mounts = mounts self._allow_elevated = allow_elevated self._allow_stdio_access = allowStdioAccess + self._seccomp_profile_sha256 = seccomp_profile_sha256 + self._user = user or {} + self._capabilities = capabilities + self._allow_privilege_escalation = allowPrivilegeEscalation self._policy_json = None self._policy_json_str = None self._policy_json_str_pp = None @@ -359,7 +594,6 @@ def __init__( def get_policy_json(self) -> str: if not self._policy_json: self._policy_json_serialization() - return self._policy_json def get_id(self) -> str: @@ -386,9 +620,18 @@ def get_layers(self) -> List[str]: def set_layers(self, layers: List[str]) -> None: self._layers = layers + def get_user(self) -> Dict: + return self._user + + def set_user(self, user: Dict) -> None: + self._user = user + def get_mounts(self) -> List: return self._mounts + def get_seccomp_profile_sha256(self) -> str: + return self._seccomp_profile_sha256 + def set_extra_environment_rules(self, rules: Dict) -> None: self._extraEnvironmentRules = rules @@ -480,11 +723,14 @@ def _populate_policy_json_elements(self) -> Dict[str, Any]: config.POLICY_FIELD_CONTAINERS_ELEMENTS_WORKINGDIR: self._workingDir, config.POLICY_FIELD_CONTAINERS_ELEMENTS_MOUNTS: self._get_mounts_json(), config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_ELEVATED: self._allow_elevated, - config.POLICY_FIELD_CONTAINER_EXEC_PROCESSES: self._exec_processes, - config.POLICY_FIELD_CONTAINER_SIGNAL_CONTAINER_PROCESSES: self._signals, - config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS: self._allow_stdio_access, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_EXEC_PROCESSES: self._exec_processes, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_SIGNAL_CONTAINER_PROCESSES: self._signals, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER: self.get_user(), + config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES: self._capabilities, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256: self._seccomp_profile_sha256, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS: self._allow_stdio_access, + config.POLICY_FIELD_CONTAINERS_ELEMENTS_NO_NEW_PRIVILEGES: not self._allow_privilege_escalation } - self._policy_json = elements return self._policy_json @@ -511,32 +757,6 @@ def from_json( image.set_extra_environment_rules(_INJECTED_CUSTOMER_ENV_RULES) return image - def __init__( - self, - containerImage: str, - environmentRules: List[Dict], - command: List[str], - mounts: List[Dict], - workingDir: str, - allowElevated: bool, - id_val: str, - execProcesses: List = None, - signals: List = None, - extraEnvironmentRules: Dict = _INJECTED_CUSTOMER_ENV_RULES, - ) -> None: - super().__init__( - containerImage=containerImage, - environmentRules=environmentRules, - command=command, - mounts=mounts, - workingDir=workingDir, - allow_elevated=allowElevated, - id_val=id_val, - signals=signals or [], - extraEnvironmentRules=extraEnvironmentRules, - execProcesses=execProcesses or [], - ) - def _populate_policy_json_elements(self) -> Dict[str, Any]: elements = super()._populate_policy_json_elements() self._policy_json = elements diff --git a/src/confcom/azext_confcom/custom.py b/src/confcom/azext_confcom/custom.py index 9dca979f94f..62f8461b599 100644 --- a/src/confcom/azext_confcom/custom.py +++ b/src/confcom/azext_confcom/custom.py @@ -116,8 +116,10 @@ def acipolicygen_confcom( elif diff: exit_code = get_diff_outputs(policy, output_type == security_policy.OutputType.PRETTY_PRINT) elif arm_template and not (print_policy_to_terminal or outraw or outraw_pretty_print): + seccomp_profile_hashes = {x.get_id(): x.get_seccomp_profile_sha256() for x in policy.get_images()} result = inject_policy_into_template(arm_template, arm_template_parameters, - policy.get_serialized_output(), count) + policy.get_serialized_output(), count, + seccomp_profile_hashes) if result: # this is always going to be the unencoded policy print(str_to_sha256(policy.get_serialized_output(OutputType.RAW))) diff --git a/src/confcom/azext_confcom/data/customer_rego_policy.txt b/src/confcom/azext_confcom/data/customer_rego_policy.txt index c8dcc4b8962..d3b891c04b0 100644 --- a/src/confcom/azext_confcom/data/customer_rego_policy.txt +++ b/src/confcom/azext_confcom/data/customer_rego_policy.txt @@ -15,8 +15,7 @@ allow_dump_stacks := %s allow_runtime_logging := %s allow_environment_variable_dropping := %s allow_unencrypted_scratch := %s - - +allow_capability_dropping := %s mount_device := data.framework.mount_device unmount_device := data.framework.unmount_device diff --git a/src/confcom/azext_confcom/data/internal_config.json b/src/confcom/azext_confcom/data/internal_config.json index 78c8413c071..9409fa9e971 100644 --- a/src/confcom/azext_confcom/data/internal_config.json +++ b/src/confcom/azext_confcom/data/internal_config.json @@ -110,6 +110,7 @@ "allowDumpStacks": true, "allowRuntimeLogging": true, "allowEnvironmentVariableDropping": true, + "allowCapabilityDropping": true, "allowUnencryptedScratch": false }, "containerd": { @@ -206,7 +207,146 @@ "signals": [], "allow_elevated": false, "allow_stdio_access": true, - "working_dir": "/" + "working_dir": "/", + "no_new_privileges": true, + "seccomp_profile_sha256": "", + "user": { + "user_idname": { + "pattern": "", + "strategy": "any" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }, + "capabilities": { + "bounding": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE" + ], + "effective": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE" + ], + "inheritable": [], + "permitted": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE" + ], + "ambient": [] + } } + ], + "default_user": { + "user_idname": { + "pattern": "", + "strategy": "any" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }, + "default_unprivileged_capabilities": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE" + ], + "default_privileged_capabilities": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" ] } \ No newline at end of file diff --git a/src/confcom/azext_confcom/sample_policy.md b/src/confcom/azext_confcom/sample_policy.md index 9f8ab74f655..eed109c2aa7 100644 --- a/src/confcom/azext_confcom/sample_policy.md +++ b/src/confcom/azext_confcom/sample_policy.md @@ -23,8 +23,6 @@ fragments := [ containers := [ { "command": ["", "", "", /*...*/], - "allow_stdio_access": true, - "signals": [/*...*/], "env_rules": [ { "pattern": "", @@ -46,15 +44,37 @@ containers := [ }, /*...*/ ], - "allow_elevated": , - "working_dir": "", "exec_processes": [ { - "command": ["", "", "", /*...*/], - "signals": [/*...*/] + "command": ["", "", "", /*...*/], + "signals": [/*...*/] }, /*...*/ ], + "signals": [/*...*/], + "user": { + "user_idname": { + "pattern": "", + "strategy": "", + }, + "group_idnames": [{ + "pattern": "", + "strategy": "", + }], + "umask": "" + }, + "capabilities": { + "ambient": ["", /*...*/], + "bounding": ["", /*...*/], + "effective": ["", /*...*/], + "inheritable": ["", /*...*/], + "permitted": ["", /*...*/] + }, + "seccomp_profile_sha256": "", + "allow_elevated": , + "working_dir": "", + "allow_stdio_access": , + "no_new_privileges": } ] @@ -63,7 +83,7 @@ allow_dump_stacks := false allow_runtime_logging := false allow_environment_variable_dropping := true allow_unencrypted_scratch := false - +allow_capabilities_dropping := true mount_device := data.framework.mount_device diff --git a/src/confcom/azext_confcom/security_policy.py b/src/confcom/azext_confcom/security_policy.py index 434ef20ba98..813c3d8747f 100644 --- a/src/confcom/azext_confcom/security_policy.py +++ b/src/confcom/azext_confcom/security_policy.py @@ -64,6 +64,7 @@ def __init__( self._fragments = rego_fragments self._existing_fragments = existing_rego_fragments self._api_version = config.API_VERSION + if debug_mode: self._allow_properties_access = config.DEBUG_MODE_SETTINGS.get( "allowPropertiesAccess" @@ -80,12 +81,16 @@ def __init__( self._allow_unencrypted_scratch = config.DEBUG_MODE_SETTINGS.get( "allowUnencryptedScratch" ) + self._allow_capability_dropping = config.DEBUG_MODE_SETTINGS.get( + "allowCapabilityDropping" + ) else: self._allow_properties_access = False self._allow_dump_stacks = False self._allow_runtime_logging = False self._allow_environment_variable_dropping = True self._allow_unencrypted_scratch = False + self._allow_capability_dropping = True self.version = case_insensitive_dict_get( deserialized_config, config.ACI_FIELD_VERSION @@ -173,7 +178,10 @@ def _add_rego_boilerplate(self, output: str) -> str: # determine if we're outputting for a sidecar or not if self._images[0].get_id() and is_sidecar(self._images[0].get_id()): - return config.SIDECAR_REGO_POLICY % (pretty_print_func(self._api_version), output) + return config.SIDECAR_REGO_POLICY % ( + pretty_print_func(self._api_version), + output + ) return config.CUSTOMER_REGO_POLICY % ( pretty_print_func(self._api_version), pretty_print_func(self._fragments), @@ -183,6 +191,7 @@ def _add_rego_boilerplate(self, output: str) -> str: pretty_print_func(self._allow_runtime_logging), pretty_print_func(self._allow_environment_variable_dropping), pretty_print_func(self._allow_unencrypted_scratch), + pretty_print_func(self._allow_capability_dropping), ) def validate_cce_policy(self) -> Tuple[bool, Dict]: @@ -335,7 +344,7 @@ def _policy_serialization(self, pretty_print=False) -> str: policy += copy.deepcopy(config.DEFAULT_CONTAINERS) if self._disable_stdio: for container in policy: - container[config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS] = False + container[config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS] = False if pretty_print: return pretty_print_func(policy) @@ -423,6 +432,32 @@ def populate_policy_content_for_all_images( } ) + if (deepdiff.DeepDiff(image.get_user(), config.DEFAULT_USER, ignore_order=True) == {} + and image_info.get("User") != ""): + # valid values are in the form "user", "user:group", "uid", "uid:gid", "user:gid", "uid:group" + # where each entry is either a string or an unsigned integer + # "" means any user (use default) + # TO-DO figure out why groups is a list + user = copy.deepcopy(config.DEFAULT_USER) + parts = image_info.get("User").split(":", 1) + + strategy = ["name", "name"] + if parts[0].isdigit(): + strategy[0] = "id" + user[config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_USER_IDNAME] = { + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_PATTERN: parts[0], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_STRATEGY: strategy[0] + } + if len(parts) == 2: + # group also specified + if parts[1].isdigit(): + strategy[1] = "id" + user[config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_GROUP_IDNAMES][0] = { + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_PATTERN: parts[1], + config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER_STRATEGY: strategy[1] + } + image.set_user(user) + # populate tar location if isinstance(tar_mapping, dict): tar_location = get_tar_location_from_mapping(tar_mapping, image_name) @@ -519,7 +554,7 @@ def load_policy_from_arm_template_str( # add init containers to the list of other containers since they aren't treated differently # in the security policy if init_container_list: - container_list = container_list + init_container_list + container_list.extend(init_container_list) existing_containers, fragments = extract_confidential_properties( container_group_properties @@ -571,6 +606,9 @@ def load_policy_from_arm_template_str( ) or [], config.ACI_FIELD_CONTAINERS_MOUNTS: process_mounts(image_properties, volumes), + config.ACI_FIELD_CONTAINERS_ALLOW_ELEVATED: case_insensitive_dict_get( + image_properties, config.ACI_FIELD_CONTAINERS_ALLOW_ELEVATED + ), config.ACI_FIELD_CONTAINERS_EXEC_PROCESSES: exec_processes + config.DEBUG_MODE_SETTINGS.get("execProcesses") if debug_mode diff --git a/src/confcom/azext_confcom/template_util.py b/src/confcom/azext_confcom/template_util.py index 7a76b6f609e..4c4a83b98cd 100644 --- a/src/confcom/azext_confcom/template_util.py +++ b/src/confcom/azext_confcom/template_util.py @@ -12,6 +12,7 @@ import deepdiff import yaml import docker +import pydash from azext_confcom.errors import ( eprint, ) @@ -327,7 +328,7 @@ def readable_diff(diff_dict) -> Dict[str, Any]: name_translation = { "values_changed": "values_changed", "iterable_item_removed": "values_removed", - "iterable_item_added": "values_added", + "iterable_item_added": "values_added" } human_readable_diff = {} @@ -666,7 +667,7 @@ def compare_env_vars( def inject_policy_into_template( - arm_template_path: str, parameter_data_path: str, policy: str, count: int + arm_template_path: str, parameter_data_path: str, policy: str, count: int, hashes: dict ) -> bool: write_flag = False parameter_data = None @@ -729,6 +730,25 @@ def inject_policy_into_template( config.ACI_FIELD_TEMPLATE_CCE_POLICY ] = policy write_flag = True + # get containers to inject the base64 encoding of seccom profile hash into template if exists + containers = case_insensitive_dict_get( + container_group_properties, config.ACI_FIELD_CONTAINERS + ) + for c in containers: + container_image = case_insensitive_dict_get(c, config.ACI_FIELD_TEMPLATE_IMAGE) + container_properties = case_insensitive_dict_get(c, config.ACI_FIELD_TEMPLATE_PROPERTIES) + security_context = case_insensitive_dict_get( + container_properties, config.ACI_FIELD_TEMPLATE_SECURITY_CONTEXT + ) + if security_context: + seccomp_profile = case_insensitive_dict_get( + security_context, config.ACI_FIELD_CONTAINERS_SECCOMP_PROFILE + ) + if seccomp_profile: + hash_base64 = os_util.str_to_base64(hashes.get(container_image, "")) + security_context[config.ACI_FIELD_CONTAINERS_SECCOMP_PROFILE] = hash_base64 + write_flag = True + # write base64 encoding of seccomp profile hash to the template if write_flag: os_util.write_json_to_file(arm_template_path, input_arm_json) return True @@ -829,3 +849,32 @@ def print_existing_policy_from_arm_template(arm_template_path, parameter_data_pa eprint("CCE Policy is either in an supported format or not present") print(f"CCE Policy for Container Group: {container_group_name}\n") print(pretty_print_func(containers)) + + +def process_seccomp_policy(policy2): + policy = json.loads(policy2) + policy = pydash.defaults(policy, {'defaultAction': ""}) + policy = pydash.pick(policy, 'defaultAction', 'defaultErrnoRet', 'architectures', + 'flags', 'listenerPath', 'listenerMetadata', 'syscalls') + if 'syscalls' in policy: + syscalls = policy['syscalls'] + temp_syscalls = [] + for s in syscalls: + syscall = s + syscall = pydash.defaults(syscall, {'names': [], 'action': ""}) + syscall = pydash.pick(syscall, 'names', 'action', 'errnoRet', 'args') + + if 'args' in syscall: + temp_args = [] + args = syscall['args'] + + for j in args: + arg = j + arg = pydash.defaults(arg, {'value': 0, 'op': "", 'index': 0}) + arg = pydash.pick(arg, 'index', 'value', 'valueTwo', 'op') + temp_args.append(arg) + syscall['args'] = temp_args + temp_syscalls.append(syscall) + # put temp_syscalls back into policy + policy['syscalls'] = temp_syscalls + return policy diff --git a/src/confcom/azext_confcom/tests/latest/README.md b/src/confcom/azext_confcom/tests/latest/README.md index 5680c87a712..19d8e07f453 100644 --- a/src/confcom/azext_confcom/tests/latest/README.md +++ b/src/confcom/azext_confcom/tests/latest/README.md @@ -21,6 +21,7 @@ Test Name | Image Used | Purpose ---|---|--- test_arm_template_policy | python:3.6.14-slim-buster | Generate an ARM Template policy and policy.json policy and see if their outputs match test_default_infrastructure_svn | python:3.6.14-slim-buster | See the default value of the minimum SVN for the infrastructure fragment +test_default_pause_container | python:3.6.14-slim-buster | See if the default pause containers match the config test_arm_template_missing_image_name | N/A | Error condition if an image isn't specified test_arm_template_missing_resources | N/A | Error condition where no resources are specified to deploy test_arm_template_missing_aci | N/A | Error condition where ACI is not specified in resources @@ -41,6 +42,20 @@ test_arm_template_policy_regex | python:3.6.14-slim-buster | Make sure the regex test_wildcard_env_var | python:3.6.14-slim-buster | Check that an "allow all" regex is created when a value for env var is not provided via a parameter value test_wildcard_env_var_invalid | N/A | Make sure the process errors out if a value is not given for an env var or an undefined parameter is used for the name of an env var test_arm_template_with_env_var | rust:1.52.1 | Make sure that a value that looks similar to but is not an ARM parameter is treated as a string +test_arm_template_security_context_defaults | N/A | Make sure default values for securityContext are correct +test_arm_template_security_context_allow_privilege_escalation | N/A | See if changing the allowPrivilegeEscalation flag is working +test_arm_template_security_context_user | N/A | Set the user field manually to make sure it is reflected in the policy +test_arm_template_security_context_seccomp_profile | N/A | Make sure we have the correct seccomp profile hash +test_arm_template_capabilities_unprivileged | N/A | See if unprivileged capabilities are in the correct sets and have the right values. Using add and drop fields +test_arm_template_capabilities_privileged | N/A | See if privilileged capabilities are correct +test_arm_template_security_context_no_run_as_group | N/A | See if user is set correctly if run_as_group is not set in ARM template +test_arm_template_security_context_no_run_as_user | N/A | See if user is set correctly if run_as_user is not set in ARM template +test_arm_template_security_context_uid_gid | N/A | See if user is set correctly by getting the user field from the Docker image in the format uid:gid +test_arm_template_security_context_user_gid | N/A | See if user is set correctly by getting the user field from the Docker image in the format user:gid +test_arm_template_security_context_user_group | N/A | See if user is set correctly by getting the user field from the Docker image in the format user:group +test_arm_template_security_context_uid_group | N/A | See if user is set correctly by getting the user field from the Docker image in the format uid:group +test_arm_template_security_context_uid | N/A | See if user is set correctly by getting the user field from the Docker image in the format uid +test_arm_template_security_context_user_dockerfile | N/A | See if user is set correctly by getting the user field from the Docker image in the format user ## policy.json [test file](test_confcom_scenario.py) @@ -52,7 +67,7 @@ Test Name | Image Used | Purpose test_user_container_customized_mounts | rust:1.52.1 | See if mounts are translated correctly to the appropriate source and destination locations test_user_container_mount_injected_dns | python:3.6.14-slim-buster | See if the resolvconf mount works properly test_injected_sidecar_container_msi | mcr.microsoft.com/aci/msi-atlas-adapter:master_20201203.1 | Make sure User mounts and env vars aren't added to sidecar containers, using JSON output format -test_logging_enabled | python:3.6.14-slim-buster | Enable logging via debug_mode +test_debug_flags | python:3.6.14-slim-buster | Enable flags set via debug_mode test_sidecar | mcr.microsoft.com/aci/msi-atlas-adapter:master_20201210.1 | See if sidecar validation would pass policy created by given policy.json test_sidecar_stdio_access_default | Check that sidecar containers have std I/O access by default test_incorrect_sidecar | mcr.microsoft.com/aci/msi-atlas-adapter:master_20201210.1 | See what output format for failing sidecar validation would be diff --git a/src/confcom/azext_confcom/tests/latest/test_confcom_arm.py b/src/confcom/azext_confcom/tests/latest/test_confcom_arm.py index 9e09535eb50..40dfc1cd13f 100644 --- a/src/confcom/azext_confcom/tests/latest/test_confcom_arm.py +++ b/src/confcom/azext_confcom/tests/latest/test_confcom_arm.py @@ -273,18 +273,14 @@ def test_default_infrastructure_svn(self): ], ) - def test_default_allow_elevated(self): + def test_default_pause_container(self): regular_image_json = json.loads( self.aci_arm_policy.get_serialized_output( output_type=OutputType.RAW, rego_boilerplate=False ) ) - - allow_elevated = regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_ELEVATED] - - # see if the remote image and the local one produce the same output - self.assertTrue(allow_elevated) - + # check default pause container + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_CONTAINERS[0], regular_image_json[1], ignore_order=True), {}) # @unittest.skip("not in use") @pytest.mark.run(order=2) @@ -619,7 +615,6 @@ def test_arm_template_missing_containers(self): load_policy_from_arm_template_str(custom_arm_json_missing_containers, "") self.assertEqual(exc_info.exception.code, 1) - # @unittest.skip("not in use") @pytest.mark.run(order=3) class PolicyGeneratingArmParametersIncorrect(unittest.TestCase): @@ -748,7 +743,6 @@ def test_arm_template_missing_definition(self): ) self.assertEqual(exc_info.exception.code, 1) - # @unittest.skip("not in use") @pytest.mark.run(order=4) class PolicyGeneratingArmParameters(unittest.TestCase): @@ -897,7 +891,6 @@ def test_arm_template_with_parameter_file(self): python_flag = True self.assertTrue(python_flag) - # @unittest.skip("not in use") @pytest.mark.run(order=5) class PolicyGeneratingArmParameters2(unittest.TestCase): @@ -1068,7 +1061,6 @@ def test_arm_template_with_parameter_file_injected_env_vars(self): python_flag = True self.assertTrue(python_flag) - # @unittest.skip("not in use") @pytest.mark.run(order=6) class PolicyGeneratingArmContainerConfig(unittest.TestCase): @@ -1262,7 +1254,6 @@ def test_arm_template_with_parameter_file_arm_config(self): for value in output_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_COMMANDS]: self.assertTrue(value in expected) - # @unittest.skip("not in use") @pytest.mark.run(order=7) class PolicyGeneratingArmParametersCleanRoom(unittest.TestCase): @@ -1450,7 +1441,6 @@ def test_arm_template_with_parameter_file_clean_room(self): {}, ) - # @unittest.skip("not in use") @pytest.mark.run(order=8) class PolicyDiff(unittest.TestCase): @@ -1471,7 +1461,7 @@ class PolicyDiff(unittest.TestCase): "properties": { "confidentialComputeProperties": { "isolationType": "SevSnp", - "ccePolicy": "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3N2biA6PSAiMC4xMC4wIgpmcmFtZXdvcmtfc3ZuIDo9ICIwLjEuMCIKCmZyYWdtZW50cyA6PSBbCiAgewogICAgImZlZWQiOiAibWNyLm1pY3Jvc29mdC5jb20vYWNpL2FjaS1jYy1pbmZyYS1mcmFnbWVudCIsCiAgICAiaW5jbHVkZXMiOiBbCiAgICAgICJjb250YWluZXJzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEuMC4wIgogIH0KXQoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6dHJ1ZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbImJhc2giXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vY3VzdG9taXplZC9wYXRoL3ZhbHVlIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFU1RfUkVHRVhQX0VOVj10ZXN0X3JlZ2V4cF9lbnYiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUlVTVFVQX0hPTUU9L3Vzci9sb2NhbC9ydXN0dXAiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiQ0FSR09fSE9NRT0vdXNyL2xvY2FsL2NhcmdvIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlJVU1RfVkVSU0lPTj0xLjUyLjEiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InJ1c3Q6MS41Mi4xIiwibGF5ZXJzIjpbImZlODRjOWQ1YmZkZGQwN2EyNjI0ZDAwMzMzY2YxM2MxYTljOTQxZjNhMjYxZjEzZWFkNDRmYzZhOTNiYzBlN2EiLCI0ZGVkYWU0Mjg0N2M3MDRkYTg5MWEyOGMyNWQzMjIwMWExYWU0NDBiY2UyYWVjY2NmYThlNmYwM2I5N2E2YTZjIiwiNDFkNjRjZGViMzQ3YmYyMzZiNGMxM2I3NDAzYjYzM2ZmMTFmMWNmOTRkYmM3Y2Y4ODFhNDRkNmRhODhjNTE1NiIsImViMzY5MjFlMWY4MmFmNDZkZmUyNDhlZjhmMWIzYWZiNmE1MjMwYTY0MTgxZDk2MGQxMDIzN2EwOGNkNzNjNzkiLCJlNzY5ZDc0ODdjYzMxNGQzZWU3NDhhNDQ0MDgwNTMxN2MxOTI2MmM3YWNkMmZkYmRiMGQ0N2QyZTQ2MTNhMTVjIiwiMWI4MGYxMjBkYmQ4OGU0MzU1ZDYyNDFiNTE5YzNlMjUyOTAyMTVjNDY5NTE2YjQ5ZGVjZTljZjA3MTc1YTc2NiJdLCJtb3VudHMiOlt7ImRlc3RpbmF0aW9uIjoiL21vdW50L2F6dXJlZmlsZSIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvYXp1cmVGaWxlVm9sdW1lLy4rIiwidHlwZSI6ImJpbmQifSx7ImRlc3RpbmF0aW9uIjoiL2V0Yy9yZXNvbHYuY29uZiIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvcmVzb2x2Y29uZi8uKyIsInR5cGUiOiJiaW5kIn1dLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY29tbWFuZCI6WyIvcGF1c2UiXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6dHJ1ZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJsYXllcnMiOlsiMTZiNTE0MDU3YTA2YWQ2NjVmOTJjMDI4NjNhY2EwNzRmZDU5NzZjNzU1ZDI2YmZmMTYzNjUyOTkxNjllODQxNSJdLCJtb3VudHMiOltdLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCgoKCm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9kZXZpY2UKdW5tb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9kZXZpY2UKbW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9vdmVybGF5CnVubW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X292ZXJsYXkKY3JlYXRlX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5jcmVhdGVfY29udGFpbmVyCmV4ZWNfaW5fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfaW5fY29udGFpbmVyCmV4ZWNfZXh0ZXJuYWwgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19leHRlcm5hbApzaHV0ZG93bl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuc2h1dGRvd25fY29udGFpbmVyCnNpZ25hbF9jb250YWluZXJfcHJvY2VzcyA6PSBkYXRhLmZyYW1ld29yay5zaWduYWxfY29udGFpbmVyX3Byb2Nlc3MKcGxhbjlfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfbW91bnQKcGxhbjlfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV91bm1vdW50CmdldF9wcm9wZXJ0aWVzIDo9IGRhdGEuZnJhbWV3b3JrLmdldF9wcm9wZXJ0aWVzCmR1bXBfc3RhY2tzIDo9IGRhdGEuZnJhbWV3b3JrLmR1bXBfc3RhY2tzCnJ1bnRpbWVfbG9nZ2luZyA6PSBkYXRhLmZyYW1ld29yay5ydW50aW1lX2xvZ2dpbmcKbG9hZF9mcmFnbWVudCA6PSBkYXRhLmZyYW1ld29yay5sb2FkX2ZyYWdtZW50CnNjcmF0Y2hfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF9tb3VudApzY3JhdGNoX3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF91bm1vdW50CgpyZWFzb24gOj0geyJlcnJvcnMiOiBkYXRhLmZyYW1ld29yay5lcnJvcnN9" + "ccePolicy": "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjp0cnVlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNhcGFiaWxpdGllcyI6eyJhbWJpZW50IjpbXSwiYm91bmRpbmciOlsiQ0FQX0FVRElUX1dSSVRFIiwiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GT1dORVIiLCJDQVBfRlNFVElEIiwiQ0FQX0tJTEwiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFBDQVAiLCJDQVBfU0VUVUlEIiwiQ0FQX1NZU19DSFJPT1QiXSwiZWZmZWN0aXZlIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImluaGVyaXRhYmxlIjpbXSwicGVybWl0dGVkIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl19LCJjb21tYW5kIjpbImJhc2giXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vY3VzdG9taXplZC9wYXRoL3ZhbHVlIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFU1RfUkVHRVhQX0VOVj10ZXN0X3JlZ2V4cF9lbnYiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUlVTVFVQX0hPTUU9L3Vzci9sb2NhbC9ydXN0dXAiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiQ0FSR09fSE9NRT0vdXNyL2xvY2FsL2NhcmdvIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlJVU1RfVkVSU0lPTj0xLjUyLjEiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InJ1c3Q6MS41Mi4xIiwibGF5ZXJzIjpbImZlODRjOWQ1YmZkZGQwN2EyNjI0ZDAwMzMzY2YxM2MxYTljOTQxZjNhMjYxZjEzZWFkNDRmYzZhOTNiYzBlN2EiLCI0ZGVkYWU0Mjg0N2M3MDRkYTg5MWEyOGMyNWQzMjIwMWExYWU0NDBiY2UyYWVjY2NmYThlNmYwM2I5N2E2YTZjIiwiNDFkNjRjZGViMzQ3YmYyMzZiNGMxM2I3NDAzYjYzM2ZmMTFmMWNmOTRkYmM3Y2Y4ODFhNDRkNmRhODhjNTE1NiIsImViMzY5MjFlMWY4MmFmNDZkZmUyNDhlZjhmMWIzYWZiNmE1MjMwYTY0MTgxZDk2MGQxMDIzN2EwOGNkNzNjNzkiLCJlNzY5ZDc0ODdjYzMxNGQzZWU3NDhhNDQ0MDgwNTMxN2MxOTI2MmM3YWNkMmZkYmRiMGQ0N2QyZTQ2MTNhMTVjIiwiMWI4MGYxMjBkYmQ4OGU0MzU1ZDYyNDFiNTE5YzNlMjUyOTAyMTVjNDY5NTE2YjQ5ZGVjZTljZjA3MTc1YTc2NiJdLCJtb3VudHMiOlt7ImRlc3RpbmF0aW9uIjoiL21vdW50L2F6dXJlZmlsZSIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvYXp1cmVGaWxlVm9sdW1lLy4rIiwidHlwZSI6ImJpbmQifSx7ImRlc3RpbmF0aW9uIjoiL2V0Yy9yZXNvbHYuY29uZiIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvcmVzb2x2Y29uZi8uKyIsInR5cGUiOiJiaW5kIn1dLCJub19uZXdfcHJpdmlsZWdlcyI6dHJ1ZSwic2VjY29tcF9wcm9maWxlX3NoYTI1NiI6IiIsInNpZ25hbHMiOltdLCJ1c2VyIjp7Imdyb3VwX2lkbmFtZXMiOlt7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9XSwidW1hc2siOiIwMDIyIiwidXNlcl9pZG5hbWUiOnsicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In19LCJ3b3JraW5nX2RpciI6Ii8ifSx7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRlNFVElEIiwiQ0FQX0ZPV05FUiIsIkNBUF9NS05PRCIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRVSUQiLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfU1lTX0NIUk9PVCIsIkNBUF9LSUxMIiwiQ0FQX0FVRElUX1dSSVRFIl0sImVmZmVjdGl2ZSI6WyJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZTRVRJRCIsIkNBUF9GT1dORVIiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUVUlEIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUUENBUCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX1NZU19DSFJPT1QiLCJDQVBfS0lMTCIsIkNBUF9BVURJVF9XUklURSJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZTRVRJRCIsIkNBUF9GT1dORVIiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUVUlEIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUUENBUCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX1NZU19DSFJPT1QiLCJDQVBfS0lMTCIsIkNBUF9BVURJVF9XUklURSJdfSwiY29tbWFuZCI6WyIvcGF1c2UiXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6dHJ1ZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJsYXllcnMiOlsiMTZiNTE0MDU3YTA2YWQ2NjVmOTJjMDI4NjNhY2EwNzRmZDU5NzZjNzU1ZDI2YmZmMTYzNjUyOTkxNjllODQxNSJdLCJtb3VudHMiOltdLCJub19uZXdfcHJpdmlsZWdlcyI6dHJ1ZSwic2VjY29tcF9wcm9maWxlX3NoYTI1NiI6IiIsInNpZ25hbHMiOltdLCJ1c2VyIjp7Imdyb3VwX2lkbmFtZXMiOlt7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9XSwidW1hc2siOiIwMDIyIiwidXNlcl9pZG5hbWUiOnsicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In19LCJ3b3JraW5nX2RpciI6Ii8ifV0KCmFsbG93X3Byb3BlcnRpZXNfYWNjZXNzIDo9IGZhbHNlCmFsbG93X2R1bXBfc3RhY2tzIDo9IGZhbHNlCmFsbG93X3J1bnRpbWVfbG9nZ2luZyA6PSBmYWxzZQphbGxvd19lbnZpcm9ubWVudF92YXJpYWJsZV9kcm9wcGluZyA6PSB0cnVlCmFsbG93X3VuZW5jcnlwdGVkX3NjcmF0Y2ggOj0gZmFsc2UKYWxsb3dfY2FwYWJpbGl0eV9kcm9wcGluZyA6PSB0cnVlCgptb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsubW91bnRfZGV2aWNlCnVubW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfZGV2aWNlCm1vdW50X292ZXJsYXkgOj0gZGF0YS5mcmFtZXdvcmsubW91bnRfb3ZlcmxheQp1bm1vdW50X292ZXJsYXkgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9vdmVybGF5CmNyZWF0ZV9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuY3JlYXRlX2NvbnRhaW5lcgpleGVjX2luX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5leGVjX2luX2NvbnRhaW5lcgpleGVjX2V4dGVybmFsIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfZXh0ZXJuYWwKc2h1dGRvd25fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLnNodXRkb3duX2NvbnRhaW5lcgpzaWduYWxfY29udGFpbmVyX3Byb2Nlc3MgOj0gZGF0YS5mcmFtZXdvcmsuc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzCnBsYW45X21vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X21vdW50CnBsYW45X3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfdW5tb3VudApnZXRfcHJvcGVydGllcyA6PSBkYXRhLmZyYW1ld29yay5nZXRfcHJvcGVydGllcwpkdW1wX3N0YWNrcyA6PSBkYXRhLmZyYW1ld29yay5kdW1wX3N0YWNrcwpydW50aW1lX2xvZ2dpbmcgOj0gZGF0YS5mcmFtZXdvcmsucnVudGltZV9sb2dnaW5nCmxvYWRfZnJhZ21lbnQgOj0gZGF0YS5mcmFtZXdvcmsubG9hZF9mcmFnbWVudApzY3JhdGNoX21vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnNjcmF0Y2hfbW91bnQKc2NyYXRjaF91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnNjcmF0Y2hfdW5tb3VudAoKcmVhc29uIDo9IHsiZXJyb3JzIjogZGF0YS5mcmFtZXdvcmsuZXJyb3JzfQ==" }, "containers": [ { @@ -1495,6 +1485,7 @@ class PolicyDiff(unittest.TestCase): "mountPath": "/mount/azurefile" } ], + "allow_elevated": true, "environmentVariables": [ { "name": "PATH", @@ -1550,13 +1541,16 @@ class PolicyDiff(unittest.TestCase): "properties": { "confidentialComputeProperties": { "isolationType": "SevSnp", - "ccePolicy": "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3N2biA6PSAiMC4xMC4wIgpmcmFtZXdvcmtfc3ZuIDo9ICIwLjEuMCIKCmZyYWdtZW50cyA6PSBbCiAgewogICAgImZlZWQiOiAibWNyLm1pY3Jvc29mdC5jb20vYWNpL2FjaS1jYy1pbmZyYS1mcmFnbWVudCIsCiAgICAiaW5jbHVkZXMiOiBbCiAgICAgICJjb250YWluZXJzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEuMC4wIgogIH0KXQoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6dHJ1ZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbImJhc2giXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vY3VzdG9taXplZC9wYXRoL3ZhbHVlIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFU1RfUkVHRVhQX0VOVj10ZXN0X3JlZ2V4cF9lbnYiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUlVTVFVQX0hPTUU9L3Vzci9sb2NhbC9ydXN0dXAiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiQ0FSR09fSE9NRT0vdXNyL2xvY2FsL2NhcmdvIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlJVU1RfVkVSU0lPTj0xLjUyLjEiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InJ1c3Q6MS41Mi4xIiwibGF5ZXJzIjpbImZlODRjOWQ1YmZkZGQwN2EyNjI0ZDAwMzMzY2YxM2MxYTljOTQxZjNhMjYxZjEzZWFkNDRmYzZhOTNiYzBlN2EiLCI0ZGVkYWU0Mjg0N2M3MDRkYTg5MWEyOGMyNWQzMjIwMWExYWU0NDBiY2UyYWVjY2NmYThlNmYwM2I5N2E2YTZjIiwiNDFkNjRjZGViMzQ3YmYyMzZiNGMxM2I3NDAzYjYzM2ZmMTFmMWNmOTRkYmM3Y2Y4ODFhNDRkNmRhODhjNTE1NiIsImViMzY5MjFlMWY4MmFmNDZkZmUyNDhlZjhmMWIzYWZiNmE1MjMwYTY0MTgxZDk2MGQxMDIzN2EwOGNkNzNjNzkiLCJlNzY5ZDc0ODdjYzMxNGQzZWU3NDhhNDQ0MDgwNTMxN2MxOTI2MmM3YWNkMmZkYmRiMGQ0N2QyZTQ2MTNhMTVjIiwiMWI4MGYxMjBkYmQ4OGU0MzU1ZDYyNDFiNTE5YzNlMjUyOTAyMTVjNDY5NTE2YjQ5ZGVjZTljZjA3MTc1YTc2NiJdLCJtb3VudHMiOlt7ImRlc3RpbmF0aW9uIjoiL21vdW50L2F6dXJlZmlsZSIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvYXp1cmVGaWxlVm9sdW1lLy4rIiwidHlwZSI6ImJpbmQifSx7ImRlc3RpbmF0aW9uIjoiL2V0Yy9yZXNvbHYuY29uZiIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvcmVzb2x2Y29uZi8uKyIsInR5cGUiOiJiaW5kIn1dLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY29tbWFuZCI6WyIvcGF1c2UiXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6dHJ1ZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJsYXllcnMiOlsiMTZiNTE0MDU3YTA2YWQ2NjVmOTJjMDI4NjNhY2EwNzRmZDU5NzZjNzU1ZDI2YmZmMTYzNjUyOTkxNjllODQxNSJdLCJtb3VudHMiOltdLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCgoKCm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9kZXZpY2UKdW5tb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9kZXZpY2UKbW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9vdmVybGF5CnVubW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X292ZXJsYXkKY3JlYXRlX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5jcmVhdGVfY29udGFpbmVyCmV4ZWNfaW5fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfaW5fY29udGFpbmVyCmV4ZWNfZXh0ZXJuYWwgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19leHRlcm5hbApzaHV0ZG93bl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuc2h1dGRvd25fY29udGFpbmVyCnNpZ25hbF9jb250YWluZXJfcHJvY2VzcyA6PSBkYXRhLmZyYW1ld29yay5zaWduYWxfY29udGFpbmVyX3Byb2Nlc3MKcGxhbjlfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfbW91bnQKcGxhbjlfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV91bm1vdW50CmdldF9wcm9wZXJ0aWVzIDo9IGRhdGEuZnJhbWV3b3JrLmdldF9wcm9wZXJ0aWVzCmR1bXBfc3RhY2tzIDo9IGRhdGEuZnJhbWV3b3JrLmR1bXBfc3RhY2tzCnJ1bnRpbWVfbG9nZ2luZyA6PSBkYXRhLmZyYW1ld29yay5ydW50aW1lX2xvZ2dpbmcKbG9hZF9mcmFnbWVudCA6PSBkYXRhLmZyYW1ld29yay5sb2FkX2ZyYWdtZW50CnNjcmF0Y2hfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF9tb3VudApzY3JhdGNoX3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF91bm1vdW50CgpyZWFzb24gOj0geyJlcnJvcnMiOiBkYXRhLmZyYW1ld29yay5lcnJvcnN9" + "ccePolicy": "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3N2biA6PSAiMC4xMC4wIgpmcmFtZXdvcmtfc3ZuIDo9ICIwLjIuMyIKCmZyYWdtZW50cyA6PSBbCiAgewogICAgImZlZWQiOiAibWNyLm1pY3Jvc29mdC5jb20vYWNpL2FjaS1jYy1pbmZyYS1mcmFnbWVudCIsCiAgICAiaW5jbHVkZXMiOiBbCiAgICAgICJjb250YWluZXJzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEuMC4wIgogIH0KXQoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6dHJ1ZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImVmZmVjdGl2ZSI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdfSwiY29tbWFuZCI6WyJiYXNoIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L2N1c3RvbWl6ZWQvcGF0aC92YWx1ZSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVNUX1JFR0VYUF9FTlY9dGVzdF9yZWdleHBfZW52IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlJVU1RVUF9IT01FPS91c3IvbG9jYWwvcnVzdHVwIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkNBUkdPX0hPTUU9L3Vzci9sb2NhbC9jYXJnbyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJSVVNUX1ZFUlNJT049MS41Mi4xIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiKCg/aSlGQUJSSUMpXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkhPU1ROQU1FPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlQoRSk/TVA9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljUGFja2FnZUZpbGVOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6Ikhvc3RlZFNlcnZpY2VOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0FQSV9WRVJTSU9OPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0hFQURFUj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9TRVJWRVJfVEhVTUJQUklOVD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlX3Jlc3RhcnRlZF9ieT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwiaWQiOiJydXN0OjEuNTIuMSIsImxheWVycyI6WyJmZTg0YzlkNWJmZGRkMDdhMjYyNGQwMDMzM2NmMTNjMWE5Yzk0MWYzYTI2MWYxM2VhZDQ0ZmM2YTkzYmMwZTdhIiwiNGRlZGFlNDI4NDdjNzA0ZGE4OTFhMjhjMjVkMzIyMDFhMWFlNDQwYmNlMmFlY2NjZmE4ZTZmMDNiOTdhNmE2YyIsIjQxZDY0Y2RlYjM0N2JmMjM2YjRjMTNiNzQwM2I2MzNmZjExZjFjZjk0ZGJjN2NmODgxYTQ0ZDZkYTg4YzUxNTYiLCJlYjM2OTIxZTFmODJhZjQ2ZGZlMjQ4ZWY4ZjFiM2FmYjZhNTIzMGE2NDE4MWQ5NjBkMTAyMzdhMDhjZDczYzc5IiwiZTc2OWQ3NDg3Y2MzMTRkM2VlNzQ4YTQ0NDA4MDUzMTdjMTkyNjJjN2FjZDJmZGJkYjBkNDdkMmU0NjEzYTE1YyIsIjFiODBmMTIwZGJkODhlNDM1NWQ2MjQxYjUxOWMzZTI1MjkwMjE1YzQ2OTUxNmI0OWRlY2U5Y2YwNzE3NWE3NjYiXSwibW91bnRzIjpbeyJkZXN0aW5hdGlvbiI6Ii9tb3VudC9henVyZWZpbGUiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL2F6dXJlRmlsZVZvbHVtZS8uKyIsInR5cGUiOiJiaW5kIn0seyJkZXN0aW5hdGlvbiI6Ii9ldGMvcmVzb2x2LmNvbmYiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL3Jlc29sdmNvbmYvLisiLCJ0eXBlIjoiYmluZCJ9XSwibm9fbmV3X3ByaXZpbGVnZXMiOmZhbHNlLCJzZWNjb21wX3Byb2ZpbGVfc2hhMjU2IjoiIiwic2lnbmFscyI6W10sInVzZXIiOnsiZ3JvdXBfaWRuYW1lcyI6W3sicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In1dLCJ1bWFzayI6IjAwMjIiLCJ1c2VyX2lkbmFtZSI6eyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifX0sIndvcmtpbmdfZGlyIjoiLyJ9LHsiYWxsb3dfZWxldmF0ZWQiOmZhbHNlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNhcGFiaWxpdGllcyI6eyJhbWJpZW50IjpbXSwiYm91bmRpbmciOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXSwiZWZmZWN0aXZlIjpbIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRlNFVElEIiwiQ0FQX0ZPV05FUiIsIkNBUF9NS05PRCIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRVSUQiLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfU1lTX0NIUk9PVCIsIkNBUF9LSUxMIiwiQ0FQX0FVRElUX1dSSVRFIl0sImluaGVyaXRhYmxlIjpbXSwicGVybWl0dGVkIjpbIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRlNFVElEIiwiQ0FQX0ZPV05FUiIsIkNBUF9NS05PRCIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRVSUQiLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfU1lTX0NIUk9PVCIsIkNBUF9LSUxMIiwiQ0FQX0FVRElUX1dSSVRFIl19LCJjb21tYW5kIjpbIi9wYXVzZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjp0cnVlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImxheWVycyI6WyIxNmI1MTQwNTdhMDZhZDY2NWY5MmMwMjg2M2FjYTA3NGZkNTk3NmM3NTVkMjZiZmYxNjM2NTI5OTE2OWU4NDE1Il0sIm1vdW50cyI6W10sIm5vX25ld19wcml2aWxlZ2VzIjp0cnVlLCJzZWNjb21wX3Byb2ZpbGVfc2hhMjU2IjoiIiwic2lnbmFscyI6W10sInVzZXIiOnsiZ3JvdXBfaWRuYW1lcyI6W3sicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In1dLCJ1bWFzayI6IjAwMjIiLCJ1c2VyX2lkbmFtZSI6eyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifX0sIndvcmtpbmdfZGlyIjoiLyJ9XQoKYWxsb3dfcHJvcGVydGllc19hY2Nlc3MgOj0gZmFsc2UKYWxsb3dfZHVtcF9zdGFja3MgOj0gZmFsc2UKYWxsb3dfcnVudGltZV9sb2dnaW5nIDo9IGZhbHNlCmFsbG93X2Vudmlyb25tZW50X3ZhcmlhYmxlX2Ryb3BwaW5nIDo9IHRydWUKYWxsb3dfdW5lbmNyeXB0ZWRfc2NyYXRjaCA6PSBmYWxzZQphbGxvd19jYXBhYmlsaXR5X2Ryb3BwaW5nIDo9IHRydWUKCm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9kZXZpY2UKdW5tb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9kZXZpY2UKbW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9vdmVybGF5CnVubW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X292ZXJsYXkKY3JlYXRlX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5jcmVhdGVfY29udGFpbmVyCmV4ZWNfaW5fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfaW5fY29udGFpbmVyCmV4ZWNfZXh0ZXJuYWwgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19leHRlcm5hbApzaHV0ZG93bl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuc2h1dGRvd25fY29udGFpbmVyCnNpZ25hbF9jb250YWluZXJfcHJvY2VzcyA6PSBkYXRhLmZyYW1ld29yay5zaWduYWxfY29udGFpbmVyX3Byb2Nlc3MKcGxhbjlfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfbW91bnQKcGxhbjlfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV91bm1vdW50CmdldF9wcm9wZXJ0aWVzIDo9IGRhdGEuZnJhbWV3b3JrLmdldF9wcm9wZXJ0aWVzCmR1bXBfc3RhY2tzIDo9IGRhdGEuZnJhbWV3b3JrLmR1bXBfc3RhY2tzCnJ1bnRpbWVfbG9nZ2luZyA6PSBkYXRhLmZyYW1ld29yay5ydW50aW1lX2xvZ2dpbmcKbG9hZF9mcmFnbWVudCA6PSBkYXRhLmZyYW1ld29yay5sb2FkX2ZyYWdtZW50CnNjcmF0Y2hfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF9tb3VudApzY3JhdGNoX3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF91bm1vdW50CgpyZWFzb24gOj0geyJlcnJvcnMiOiBkYXRhLmZyYW1ld29yay5lcnJvcnN9" }, "containers": [ { "name": "[variables('container1name')]", "properties": { "image": "[variables('container1image')]", + "securityContext": { + "allowPrivilegeEscalation": false + }, "resources": { "requests": { "cpu": 1, @@ -1574,6 +1568,7 @@ class PolicyDiff(unittest.TestCase): "mountPath": "/mount/azure" } ], + "allow_elevated": true, "environmentVariables": [ { "name": "PATH", @@ -1629,13 +1624,11 @@ def setUpClass(cls): cls.aci_policy2.populate_policy_content_for_all_images() def test_policy_diff(self): - is_valid, diff = self.aci_policy.validate_cce_policy() self.assertTrue(is_valid) self.assertTrue(not diff) def test_incorrect_policy_diff(self): - is_valid, diff = self.aci_policy2.validate_cce_policy() self.assertFalse(is_valid) expected_diff = { @@ -1646,7 +1639,8 @@ def test_incorrect_policy_diff(self): "tested_value": "/mount/azure", "policy_value": "/mount/azurefile", } - ] + ], + "no_new_privileges": [{"tested_value": True, "policy_value": False}] }, "env_rules": [ "environment variable with rule 'TEST_REGEXP_ENV=test_regexp_en' does not match strings or regex in policy rules", @@ -1654,10 +1648,8 @@ def test_incorrect_policy_diff(self): ], } } - self.assertEqual(diff, expected_diff) - # @unittest.skip("not in use") @pytest.mark.run(order=9) class PolicyGeneratingArmInfrastructureSvn(unittest.TestCase): @@ -1811,8 +1803,7 @@ def setUpClass(cls): cls.aci_arm_policy.populate_policy_content_for_all_images() def test_update_infrastructure_svn(self): - expected_policy = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjIiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjp0cnVlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNvbW1hbmQiOlsicHl0aG9uMyJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvYmluOi91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJMQU5HPUMuVVRGLTgiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiR1BHX0tFWT0wRDk2REY0RDQxMTBFNUM0M0ZCRkIxN0YyRDM0N0VBNkFBNjU0MjFEIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9WRVJTSU9OPTMuNi4xNCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJQWVRIT05fUElQX1ZFUlNJT049MjEuMi40IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9HRVRfUElQX1VSTD1odHRwczovL2dpdGh1Yi5jb20vcHlwYS9nZXQtcGlwL3Jhdy9jMjBiMGNmZDY0M2NkNGExOTI0NmNjZjIwNGUyOTk3YWY3MGY2YjIxL3B1YmxpYy9nZXQtcGlwLnB5IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9HRVRfUElQX1NIQTI1Nj1mYTZmM2ZiOTNjY2UyMzRjZDRlOGRkMmJlYjU0YTUxYWI5YzI0NzY1M2I1Mjg1NWE0OGRkNDRlNmIyMWZmMjhiIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiKCg/aSlGQUJSSUMpXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkhPU1ROQU1FPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlQoRSk/TVA9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljUGFja2FnZUZpbGVOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6Ikhvc3RlZFNlcnZpY2VOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0FQSV9WRVJTSU9OPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0hFQURFUj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9TRVJWRVJfVEhVTUJQUklOVD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlX3Jlc3RhcnRlZF9ieT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwiaWQiOiJweXRob246My42LjE0LXNsaW0tYnVzdGVyIiwibGF5ZXJzIjpbIjI1NGNjODUzZGE2MDgxOTA1YzkxMDljOGI5ZDk5YzlmYjA5ODdiYTFkODhmNzI5MDg4OTAzY2ZmYjgwZjU1ZjEiLCJhNTY4ZjE5MDBiZWQ2MGEwNjQxYjc2Yjk5MWFkNDMxNDQ2ZDljM2EzNDRkN2IyNjFmMTBkZThkOGU3Mzc2M2FjIiwiYzcwYzUzMGU4NDJmNjYyMTViMGJkOTU1ODc3MTU3YmEyNGMzNzk5MzAzNTY3YzNmNTY3M2M0NTY2M2VhNGQxNSIsIjNlODZjM2NjZjE2NDJiZjU4NGRlMzNiNDljNzI0OGY4N2VlY2QwZjZkOGMwODM1M2RhYTM2Y2M3YWQwYTdiNmEiLCIxZTQ2ODRkOGM3Y2FhNzRjNjUyNDE3MmI0ZDVhMTU5YTEwODg3NjEzZWQ3MGYxOGQwYTU1ZDA1YjJhZjYxYWNkIl0sIm1vdW50cyI6W3siZGVzdGluYXRpb24iOiIvYWNpL2xvZ3MiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL2F6dXJlRmlsZVZvbHVtZS8uKyIsInR5cGUiOiJiaW5kIn0seyJkZXN0aW5hdGlvbiI6Ii9hY2kvc2VjcmV0Iiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJybyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9zZWNyZXRzVm9sdW1lLy4rIiwidHlwZSI6ImJpbmQifSx7ImRlc3RpbmF0aW9uIjoiL2V0Yy9yZXNvbHYuY29uZiIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvcmVzb2x2Y29uZi8uKyIsInR5cGUiOiJiaW5kIn1dLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY29tbWFuZCI6WyIvcGF1c2UiXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6dHJ1ZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJsYXllcnMiOlsiMTZiNTE0MDU3YTA2YWQ2NjVmOTJjMDI4NjNhY2EwNzRmZDU5NzZjNzU1ZDI2YmZmMTYzNjUyOTkxNjllODQxNSJdLCJtb3VudHMiOltdLCJzaWduYWxzIjpbXSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCgoKCm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9kZXZpY2UKdW5tb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9kZXZpY2UKbW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9vdmVybGF5CnVubW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X292ZXJsYXkKY3JlYXRlX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5jcmVhdGVfY29udGFpbmVyCmV4ZWNfaW5fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfaW5fY29udGFpbmVyCmV4ZWNfZXh0ZXJuYWwgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19leHRlcm5hbApzaHV0ZG93bl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuc2h1dGRvd25fY29udGFpbmVyCnNpZ25hbF9jb250YWluZXJfcHJvY2VzcyA6PSBkYXRhLmZyYW1ld29yay5zaWduYWxfY29udGFpbmVyX3Byb2Nlc3MKcGxhbjlfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfbW91bnQKcGxhbjlfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV91bm1vdW50CmdldF9wcm9wZXJ0aWVzIDo9IGRhdGEuZnJhbWV3b3JrLmdldF9wcm9wZXJ0aWVzCmR1bXBfc3RhY2tzIDo9IGRhdGEuZnJhbWV3b3JrLmR1bXBfc3RhY2tzCnJ1bnRpbWVfbG9nZ2luZyA6PSBkYXRhLmZyYW1ld29yay5ydW50aW1lX2xvZ2dpbmcKbG9hZF9mcmFnbWVudCA6PSBkYXRhLmZyYW1ld29yay5sb2FkX2ZyYWdtZW50CnNjcmF0Y2hfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF9tb3VudApzY3JhdGNoX3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF91bm1vdW50CgpyZWFzb24gOj0geyJlcnJvcnMiOiBkYXRhLmZyYW1ld29yay5lcnJvcnN9" - + expected_policy = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjIiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImVmZmVjdGl2ZSI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdfSwiY29tbWFuZCI6WyJweXRob24zIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkxBTkc9Qy5VVEYtOCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJHUEdfS0VZPTBEOTZERjRENDExMEU1QzQzRkJGQjE3RjJEMzQ3RUE2QUE2NTQyMUQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX1ZFUlNJT049My42LjE0IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9QSVBfVkVSU0lPTj0yMS4yLjQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9weXBhL2dldC1waXAvcmF3L2MyMGIwY2ZkNjQzY2Q0YTE5MjQ2Y2NmMjA0ZTI5OTdhZjcwZjZiMjEvcHVibGljL2dldC1waXAucHkiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfU0hBMjU2PWZhNmYzZmI5M2NjZTIzNGNkNGU4ZGQyYmViNTRhNTFhYjljMjQ3NjUzYjUyODU1YTQ4ZGQ0NGU2YjIxZmYyOGIiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InB5dGhvbjozLjYuMTQtc2xpbS1idXN0ZXIiLCJsYXllcnMiOlsiMjU0Y2M4NTNkYTYwODE5MDVjOTEwOWM4YjlkOTljOWZiMDk4N2JhMWQ4OGY3MjkwODg5MDNjZmZiODBmNTVmMSIsImE1NjhmMTkwMGJlZDYwYTA2NDFiNzZiOTkxYWQ0MzE0NDZkOWMzYTM0NGQ3YjI2MWYxMGRlOGQ4ZTczNzYzYWMiLCJjNzBjNTMwZTg0MmY2NjIxNWIwYmQ5NTU4NzcxNTdiYTI0YzM3OTkzMDM1NjdjM2Y1NjczYzQ1NjYzZWE0ZDE1IiwiM2U4NmMzY2NmMTY0MmJmNTg0ZGUzM2I0OWM3MjQ4Zjg3ZWVjZDBmNmQ4YzA4MzUzZGFhMzZjYzdhZDBhN2I2YSIsIjFlNDY4NGQ4YzdjYWE3NGM2NTI0MTcyYjRkNWExNTlhMTA4ODc2MTNlZDcwZjE4ZDBhNTVkMDViMmFmNjFhY2QiXSwibW91bnRzIjpbeyJkZXN0aW5hdGlvbiI6Ii9hY2kvbG9ncyIsIm9wdGlvbnMiOlsicmJpbmQiLCJyc2hhcmVkIiwicnciXSwic291cmNlIjoic2FuZGJveDovLy90bXAvYXRsYXMvYXp1cmVGaWxlVm9sdW1lLy4rIiwidHlwZSI6ImJpbmQifSx7ImRlc3RpbmF0aW9uIjoiL2FjaS9zZWNyZXQiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJvIl0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL3NlY3JldHNWb2x1bWUvLisiLCJ0eXBlIjoiYmluZCJ9LHsiZGVzdGluYXRpb24iOiIvZXRjL3Jlc29sdi5jb25mIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9yZXNvbHZjb25mLy4rIiwidHlwZSI6ImJpbmQifV0sIm5vX25ld19wcml2aWxlZ2VzIjp0cnVlLCJzZWNjb21wX3Byb2ZpbGVfc2hhMjU2IjoiIiwic2lnbmFscyI6W10sInVzZXIiOnsiZ3JvdXBfaWRuYW1lcyI6W3sicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In1dLCJ1bWFzayI6IjAwMjIiLCJ1c2VyX2lkbmFtZSI6eyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifX0sIndvcmtpbmdfZGlyIjoiLyJ9LHsiYWxsb3dfZWxldmF0ZWQiOmZhbHNlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNhcGFiaWxpdGllcyI6eyJhbWJpZW50IjpbXSwiYm91bmRpbmciOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXSwiZWZmZWN0aXZlIjpbIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRlNFVElEIiwiQ0FQX0ZPV05FUiIsIkNBUF9NS05PRCIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRVSUQiLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfU1lTX0NIUk9PVCIsIkNBUF9LSUxMIiwiQ0FQX0FVRElUX1dSSVRFIl0sImluaGVyaXRhYmxlIjpbXSwicGVybWl0dGVkIjpbIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRlNFVElEIiwiQ0FQX0ZPV05FUiIsIkNBUF9NS05PRCIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRVSUQiLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfU1lTX0NIUk9PVCIsIkNBUF9LSUxMIiwiQ0FQX0FVRElUX1dSSVRFIl19LCJjb21tYW5kIjpbIi9wYXVzZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjp0cnVlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImxheWVycyI6WyIxNmI1MTQwNTdhMDZhZDY2NWY5MmMwMjg2M2FjYTA3NGZkNTk3NmM3NTVkMjZiZmYxNjM2NTI5OTE2OWU4NDE1Il0sIm1vdW50cyI6W10sIm5vX25ld19wcml2aWxlZ2VzIjp0cnVlLCJzZWNjb21wX3Byb2ZpbGVfc2hhMjU2IjoiIiwic2lnbmFscyI6W10sInVzZXIiOnsiZ3JvdXBfaWRuYW1lcyI6W3sicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In1dLCJ1bWFzayI6IjAwMjIiLCJ1c2VyX2lkbmFtZSI6eyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifX0sIndvcmtpbmdfZGlyIjoiLyJ9XQoKYWxsb3dfcHJvcGVydGllc19hY2Nlc3MgOj0gZmFsc2UKYWxsb3dfZHVtcF9zdGFja3MgOj0gZmFsc2UKYWxsb3dfcnVudGltZV9sb2dnaW5nIDo9IGZhbHNlCmFsbG93X2Vudmlyb25tZW50X3ZhcmlhYmxlX2Ryb3BwaW5nIDo9IHRydWUKYWxsb3dfdW5lbmNyeXB0ZWRfc2NyYXRjaCA6PSBmYWxzZQphbGxvd19jYXBhYmlsaXR5X2Ryb3BwaW5nIDo9IHRydWUKCm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9kZXZpY2UKdW5tb3VudF9kZXZpY2UgOj0gZGF0YS5mcmFtZXdvcmsudW5tb3VudF9kZXZpY2UKbW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay5tb3VudF9vdmVybGF5CnVubW91bnRfb3ZlcmxheSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X292ZXJsYXkKY3JlYXRlX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5jcmVhdGVfY29udGFpbmVyCmV4ZWNfaW5fY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmV4ZWNfaW5fY29udGFpbmVyCmV4ZWNfZXh0ZXJuYWwgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19leHRlcm5hbApzaHV0ZG93bl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuc2h1dGRvd25fY29udGFpbmVyCnNpZ25hbF9jb250YWluZXJfcHJvY2VzcyA6PSBkYXRhLmZyYW1ld29yay5zaWduYWxfY29udGFpbmVyX3Byb2Nlc3MKcGxhbjlfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsucGxhbjlfbW91bnQKcGxhbjlfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV91bm1vdW50CmdldF9wcm9wZXJ0aWVzIDo9IGRhdGEuZnJhbWV3b3JrLmdldF9wcm9wZXJ0aWVzCmR1bXBfc3RhY2tzIDo9IGRhdGEuZnJhbWV3b3JrLmR1bXBfc3RhY2tzCnJ1bnRpbWVfbG9nZ2luZyA6PSBkYXRhLmZyYW1ld29yay5ydW50aW1lX2xvZ2dpbmcKbG9hZF9mcmFnbWVudCA6PSBkYXRhLmZyYW1ld29yay5sb2FkX2ZyYWdtZW50CnNjcmF0Y2hfbW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF9tb3VudApzY3JhdGNoX3VubW91bnQgOj0gZGF0YS5mcmFtZXdvcmsuc2NyYXRjaF91bm1vdW50CgpyZWFzb24gOj0geyJlcnJvcnMiOiBkYXRhLmZyYW1ld29yay5lcnJvcnN9" self.assertEqual(expected_policy, self.aci_arm_policy.get_serialized_output()) self.assertEqual( @@ -1822,7 +1813,6 @@ def test_update_infrastructure_svn(self): ], ) - # @unittest.skip("not in use") @pytest.mark.run(order=10) class MultiplePolicyTemplate(unittest.TestCase): @@ -1996,13 +1986,12 @@ def test_multiple_policies(self): output2 = self.aci_policy2.get_serialized_output() self.assertTrue(output1 != output2) - expected_output1 = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjp0cnVlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNvbW1hbmQiOlsiYmFzaCJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS9jdXN0b21pemVkL3BhdGgvdmFsdWUiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVTVF9SRUdFWFBfRU5WPXRlc3RfcmVnZXhwX2VudiIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJSVVNUVVBfSE9NRT0vdXNyL2xvY2FsL3J1c3R1cCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJDQVJHT19IT01FPS91c3IvbG9jYWwvY2FyZ28iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUlVTVF9WRVJTSU9OPTEuNTIuMSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IigoP2kpRkFCUklDKV8uKz0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJIT1NUTkFNRT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJUKEUpP01QPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY1BhY2thZ2VGaWxlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJIb3N0ZWRTZXJ2aWNlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9BUElfVkVSU0lPTj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9IRUFERVI9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfU0VSVkVSX1RIVU1CUFJJTlQ9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiYXp1cmVjb250YWluZXJpbnN0YW5jZV9yZXN0YXJ0ZWRfYnk9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImlkIjoicnVzdDoxLjUyLjEiLCJsYXllcnMiOlsiZmU4NGM5ZDViZmRkZDA3YTI2MjRkMDAzMzNjZjEzYzFhOWM5NDFmM2EyNjFmMTNlYWQ0NGZjNmE5M2JjMGU3YSIsIjRkZWRhZTQyODQ3YzcwNGRhODkxYTI4YzI1ZDMyMjAxYTFhZTQ0MGJjZTJhZWNjY2ZhOGU2ZjAzYjk3YTZhNmMiLCI0MWQ2NGNkZWIzNDdiZjIzNmI0YzEzYjc0MDNiNjMzZmYxMWYxY2Y5NGRiYzdjZjg4MWE0NGQ2ZGE4OGM1MTU2IiwiZWIzNjkyMWUxZjgyYWY0NmRmZTI0OGVmOGYxYjNhZmI2YTUyMzBhNjQxODFkOTYwZDEwMjM3YTA4Y2Q3M2M3OSIsImU3NjlkNzQ4N2NjMzE0ZDNlZTc0OGE0NDQwODA1MzE3YzE5MjYyYzdhY2QyZmRiZGIwZDQ3ZDJlNDYxM2ExNWMiLCIxYjgwZjEyMGRiZDg4ZTQzNTVkNjI0MWI1MTljM2UyNTI5MDIxNWM0Njk1MTZiNDlkZWNlOWNmMDcxNzVhNzY2Il0sIm1vdW50cyI6W3siZGVzdGluYXRpb24iOiIvbW91bnQvYXp1cmVmaWxlIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9henVyZUZpbGVWb2x1bWUvLisiLCJ0eXBlIjoiYmluZCJ9LHsiZGVzdGluYXRpb24iOiIvZXRjL3Jlc29sdi5jb25mIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9yZXNvbHZjb25mLy4rIiwidHlwZSI6ImJpbmQifV0sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifSx7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbIi9wYXVzZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjp0cnVlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImxheWVycyI6WyIxNmI1MTQwNTdhMDZhZDY2NWY5MmMwMjg2M2FjYTA3NGZkNTk3NmM3NTVkMjZiZmYxNjM2NTI5OTE2OWU4NDE1Il0sIm1vdW50cyI6W10sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifV0KCmFsbG93X3Byb3BlcnRpZXNfYWNjZXNzIDo9IGZhbHNlCmFsbG93X2R1bXBfc3RhY2tzIDo9IGZhbHNlCmFsbG93X3J1bnRpbWVfbG9nZ2luZyA6PSBmYWxzZQphbGxvd19lbnZpcm9ubWVudF92YXJpYWJsZV9kcm9wcGluZyA6PSB0cnVlCmFsbG93X3VuZW5jcnlwdGVkX3NjcmF0Y2ggOj0gZmFsc2UKCgoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" - expected_output2 = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjp0cnVlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNvbW1hbmQiOlsicHl0aG9uMyJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS9jdXN0b21pemVkL2RpZmZlcmVudC9wYXRoL3ZhbHVlIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkxBTkc9Qy5VVEYtOCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJHUEdfS0VZPTBEOTZERjRENDExMEU1QzQzRkJGQjE3RjJEMzQ3RUE2QUE2NTQyMUQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX1ZFUlNJT049My42LjE0IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9QSVBfVkVSU0lPTj0yMS4yLjQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9weXBhL2dldC1waXAvcmF3L2MyMGIwY2ZkNjQzY2Q0YTE5MjQ2Y2NmMjA0ZTI5OTdhZjcwZjZiMjEvcHVibGljL2dldC1waXAucHkiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfU0hBMjU2PWZhNmYzZmI5M2NjZTIzNGNkNGU4ZGQyYmViNTRhNTFhYjljMjQ3NjUzYjUyODU1YTQ4ZGQ0NGU2YjIxZmYyOGIiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InB5dGhvbjozLjYuMTQtc2xpbS1idXN0ZXIiLCJsYXllcnMiOlsiMjU0Y2M4NTNkYTYwODE5MDVjOTEwOWM4YjlkOTljOWZiMDk4N2JhMWQ4OGY3MjkwODg5MDNjZmZiODBmNTVmMSIsImE1NjhmMTkwMGJlZDYwYTA2NDFiNzZiOTkxYWQ0MzE0NDZkOWMzYTM0NGQ3YjI2MWYxMGRlOGQ4ZTczNzYzYWMiLCJjNzBjNTMwZTg0MmY2NjIxNWIwYmQ5NTU4NzcxNTdiYTI0YzM3OTkzMDM1NjdjM2Y1NjczYzQ1NjYzZWE0ZDE1IiwiM2U4NmMzY2NmMTY0MmJmNTg0ZGUzM2I0OWM3MjQ4Zjg3ZWVjZDBmNmQ4YzA4MzUzZGFhMzZjYzdhZDBhN2I2YSIsIjFlNDY4NGQ4YzdjYWE3NGM2NTI0MTcyYjRkNWExNTlhMTA4ODc2MTNlZDcwZjE4ZDBhNTVkMDViMmFmNjFhY2QiXSwibW91bnRzIjpbeyJkZXN0aW5hdGlvbiI6Ii9tb3VudC9maWxlIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9henVyZUZpbGVWb2x1bWUvLisiLCJ0eXBlIjoiYmluZCJ9LHsiZGVzdGluYXRpb24iOiIvZXRjL3Jlc29sdi5jb25mIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9yZXNvbHZjb25mLy4rIiwidHlwZSI6ImJpbmQifV0sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifSx7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbIi9wYXVzZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjp0cnVlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImxheWVycyI6WyIxNmI1MTQwNTdhMDZhZDY2NWY5MmMwMjg2M2FjYTA3NGZkNTk3NmM3NTVkMjZiZmYxNjM2NTI5OTE2OWU4NDE1Il0sIm1vdW50cyI6W10sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifV0KCmFsbG93X3Byb3BlcnRpZXNfYWNjZXNzIDo9IGZhbHNlCmFsbG93X2R1bXBfc3RhY2tzIDo9IGZhbHNlCmFsbG93X3J1bnRpbWVfbG9nZ2luZyA6PSBmYWxzZQphbGxvd19lbnZpcm9ubWVudF92YXJpYWJsZV9kcm9wcGluZyA6PSB0cnVlCmFsbG93X3VuZW5jcnlwdGVkX3NjcmF0Y2ggOj0gZmFsc2UKCgoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" - + expected_output1 = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImVmZmVjdGl2ZSI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdfSwiY29tbWFuZCI6WyJiYXNoIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L2N1c3RvbWl6ZWQvcGF0aC92YWx1ZSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVNUX1JFR0VYUF9FTlY9dGVzdF9yZWdleHBfZW52IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlJVU1RVUF9IT01FPS91c3IvbG9jYWwvcnVzdHVwIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkNBUkdPX0hPTUU9L3Vzci9sb2NhbC9jYXJnbyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJSVVNUX1ZFUlNJT049MS41Mi4xIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiKCg/aSlGQUJSSUMpXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkhPU1ROQU1FPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlQoRSk/TVA9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljUGFja2FnZUZpbGVOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6Ikhvc3RlZFNlcnZpY2VOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0FQSV9WRVJTSU9OPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0hFQURFUj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9TRVJWRVJfVEhVTUJQUklOVD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlX3Jlc3RhcnRlZF9ieT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwiaWQiOiJydXN0OjEuNTIuMSIsImxheWVycyI6WyJmZTg0YzlkNWJmZGRkMDdhMjYyNGQwMDMzM2NmMTNjMWE5Yzk0MWYzYTI2MWYxM2VhZDQ0ZmM2YTkzYmMwZTdhIiwiNGRlZGFlNDI4NDdjNzA0ZGE4OTFhMjhjMjVkMzIyMDFhMWFlNDQwYmNlMmFlY2NjZmE4ZTZmMDNiOTdhNmE2YyIsIjQxZDY0Y2RlYjM0N2JmMjM2YjRjMTNiNzQwM2I2MzNmZjExZjFjZjk0ZGJjN2NmODgxYTQ0ZDZkYTg4YzUxNTYiLCJlYjM2OTIxZTFmODJhZjQ2ZGZlMjQ4ZWY4ZjFiM2FmYjZhNTIzMGE2NDE4MWQ5NjBkMTAyMzdhMDhjZDczYzc5IiwiZTc2OWQ3NDg3Y2MzMTRkM2VlNzQ4YTQ0NDA4MDUzMTdjMTkyNjJjN2FjZDJmZGJkYjBkNDdkMmU0NjEzYTE1YyIsIjFiODBmMTIwZGJkODhlNDM1NWQ2MjQxYjUxOWMzZTI1MjkwMjE1YzQ2OTUxNmI0OWRlY2U5Y2YwNzE3NWE3NjYiXSwibW91bnRzIjpbeyJkZXN0aW5hdGlvbiI6Ii9tb3VudC9henVyZWZpbGUiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL2F6dXJlRmlsZVZvbHVtZS8uKyIsInR5cGUiOiJiaW5kIn0seyJkZXN0aW5hdGlvbiI6Ii9ldGMvcmVzb2x2LmNvbmYiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL3Jlc29sdmNvbmYvLisiLCJ0eXBlIjoiYmluZCJ9XSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY2FwYWJpbGl0aWVzIjp7ImFtYmllbnQiOltdLCJib3VuZGluZyI6WyJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZTRVRJRCIsIkNBUF9GT1dORVIiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUVUlEIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUUENBUCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX1NZU19DSFJPT1QiLCJDQVBfS0lMTCIsIkNBUF9BVURJVF9XUklURSJdLCJlZmZlY3RpdmUiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXSwiaW5oZXJpdGFibGUiOltdLCJwZXJtaXR0ZWQiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXX0sImNvbW1hbmQiOlsiL3BhdXNlIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOnRydWUsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwibGF5ZXJzIjpbIjE2YjUxNDA1N2EwNmFkNjY1ZjkyYzAyODYzYWNhMDc0ZmQ1OTc2Yzc1NWQyNmJmZjE2MzY1Mjk5MTY5ZTg0MTUiXSwibW91bnRzIjpbXSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCmFsbG93X2NhcGFiaWxpdHlfZHJvcHBpbmcgOj0gdHJ1ZQoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" + expected_output2 = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImVmZmVjdGl2ZSI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdfSwiY29tbWFuZCI6WyJweXRob24zIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L2N1c3RvbWl6ZWQvZGlmZmVyZW50L3BhdGgvdmFsdWUiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiTEFORz1DLlVURi04IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkdQR19LRVk9MEQ5NkRGNEQ0MTEwRTVDNDNGQkZCMTdGMkQzNDdFQTZBQTY1NDIxRCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJQWVRIT05fVkVSU0lPTj0zLjYuMTQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX1BJUF9WRVJTSU9OPTIxLjIuNCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJQWVRIT05fR0VUX1BJUF9VUkw9aHR0cHM6Ly9naXRodWIuY29tL3B5cGEvZ2V0LXBpcC9yYXcvYzIwYjBjZmQ2NDNjZDRhMTkyNDZjY2YyMDRlMjk5N2FmNzBmNmIyMS9wdWJsaWMvZ2V0LXBpcC5weSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJQWVRIT05fR0VUX1BJUF9TSEEyNTY9ZmE2ZjNmYjkzY2NlMjM0Y2Q0ZThkZDJiZWI1NGE1MWFiOWMyNDc2NTNiNTI4NTVhNDhkZDQ0ZTZiMjFmZjI4YiIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IigoP2kpRkFCUklDKV8uKz0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJIT1NUTkFNRT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJUKEUpP01QPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY1BhY2thZ2VGaWxlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJIb3N0ZWRTZXJ2aWNlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9BUElfVkVSU0lPTj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9IRUFERVI9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfU0VSVkVSX1RIVU1CUFJJTlQ9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiYXp1cmVjb250YWluZXJpbnN0YW5jZV9yZXN0YXJ0ZWRfYnk9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImlkIjoicHl0aG9uOjMuNi4xNC1zbGltLWJ1c3RlciIsImxheWVycyI6WyIyNTRjYzg1M2RhNjA4MTkwNWM5MTA5YzhiOWQ5OWM5ZmIwOTg3YmExZDg4ZjcyOTA4ODkwM2NmZmI4MGY1NWYxIiwiYTU2OGYxOTAwYmVkNjBhMDY0MWI3NmI5OTFhZDQzMTQ0NmQ5YzNhMzQ0ZDdiMjYxZjEwZGU4ZDhlNzM3NjNhYyIsImM3MGM1MzBlODQyZjY2MjE1YjBiZDk1NTg3NzE1N2JhMjRjMzc5OTMwMzU2N2MzZjU2NzNjNDU2NjNlYTRkMTUiLCIzZTg2YzNjY2YxNjQyYmY1ODRkZTMzYjQ5YzcyNDhmODdlZWNkMGY2ZDhjMDgzNTNkYWEzNmNjN2FkMGE3YjZhIiwiMWU0Njg0ZDhjN2NhYTc0YzY1MjQxNzJiNGQ1YTE1OWExMDg4NzYxM2VkNzBmMThkMGE1NWQwNWIyYWY2MWFjZCJdLCJtb3VudHMiOlt7ImRlc3RpbmF0aW9uIjoiL21vdW50L2ZpbGUiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL2F6dXJlRmlsZVZvbHVtZS8uKyIsInR5cGUiOiJiaW5kIn0seyJkZXN0aW5hdGlvbiI6Ii9ldGMvcmVzb2x2LmNvbmYiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL3Jlc29sdmNvbmYvLisiLCJ0eXBlIjoiYmluZCJ9XSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY2FwYWJpbGl0aWVzIjp7ImFtYmllbnQiOltdLCJib3VuZGluZyI6WyJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZTRVRJRCIsIkNBUF9GT1dORVIiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUVUlEIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUUENBUCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX1NZU19DSFJPT1QiLCJDQVBfS0lMTCIsIkNBUF9BVURJVF9XUklURSJdLCJlZmZlY3RpdmUiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXSwiaW5oZXJpdGFibGUiOltdLCJwZXJtaXR0ZWQiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXX0sImNvbW1hbmQiOlsiL3BhdXNlIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOnRydWUsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwibGF5ZXJzIjpbIjE2YjUxNDA1N2EwNmFkNjY1ZjkyYzAyODYzYWNhMDc0ZmQ1OTc2Yzc1NWQyNmJmZjE2MzY1Mjk5MTY5ZTg0MTUiXSwibW91bnRzIjpbXSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCmFsbG93X2NhcGFiaWxpdHlfZHJvcHBpbmcgOj0gdHJ1ZQoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" + self.assertEqual(output1, expected_output1) self.assertEqual(output2, expected_output2) - # @unittest.skip("not in use") @pytest.mark.run(order=11) class PolicyGeneratingArmInitContainer(unittest.TestCase): @@ -2189,7 +2178,6 @@ def test_arm_template_with_init_container(self): # see if the remote image and the local one produce the same output self.assertTrue("python" in python_image_name) - # @unittest.skip("not in use") @pytest.mark.run(order=12) class PolicyGeneratingDisableStdioAccess(unittest.TestCase): @@ -2332,12 +2320,11 @@ def test_arm_template_without_stdio_access(self): ) ) - stdio_access = regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS] + stdio_access = regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS] # see if the remote image and the local one produce the same output self.assertFalse(stdio_access) - # @unittest.skip("not in use") @pytest.mark.run(order=13) class PolicyGeneratingAllowElevated(unittest.TestCase): @@ -3453,7 +3440,6 @@ def test_wildcard_env_var_invalid(self): self.assertEqual(wrapped_exit.exception.code, 1) - # @unittest.skip("not in use") @pytest.mark.run(order=16) class PolicyGeneratingEdgeCases(unittest.TestCase): @@ -3600,4 +3586,1734 @@ def test_arm_template_with_env_var(self): # see if the remote image and the local one produce the same output self.assertEquals(env_var, "PORT=parameters('abc')") - self.assertEquals(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ID], "rust:1.52.1") \ No newline at end of file + self.assertEquals(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ID], "rust:1.52.1") + +# @unittest.skip("not in use") +@pytest.mark.run(order=16) +class PolicyGeneratingSecurityContext(unittest.TestCase): + custom_arm_json = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + custom_arm_json2 = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext": { + "privileged": "false", + "capabilities":{ + "add": ["CAP_SYS_TIME","CAP_DAC_READ_SEARCH"], + "drop": ["CAP_CHOWN","CAP_KILL"] + }, + "runAsGroup": 123, + "runAsUser": 456, + "seccompProfile": "seccompStr" + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "allow_elevated": true, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + + custom_arm_json3 = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext":{ + "privileged": true, + "allowPrivilegeEscalation": true, + "runAsGroup":123, + "runAsUser":456 + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + custom_arm_json4 = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext": { + "privileged": "false", + "capabilities":{ + "add": ["CAP_SYS_TIME","CAP_DAC_READ_SEARCH"], + "drop": ["CAP_CHOWN","CAP_KILL"] + }, + "runAsGroup": 123, + "runAsUser": 456 + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "allow_elevated": false, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + @classmethod + def setUpClass(cls): + seccomp_profile_contents = "ewoJImNvbW1lbnQiOiAiRGVmYXVsdCBtb2J5IHNlY2NvbXAgcG9saWN5IGNvbmZpZyBmaWxlIGF0OiBodHRwczovL2dpdGh1Yi5jb20vbW9ieS9tb2J5L2Jsb2IvbWFzdGVyL3Byb2ZpbGVzL3NlY2NvbXAvZGVmYXVsdC5qc29uIiwKCSJkZWZhdWx0QWN0aW9uIjogIlNDTVBfQUNUX0VSUk5PIiwKCSJkZWZhdWx0RXJybm9SZXQiOiAxLAoJImFyY2hNYXAiOiBbCgkJewoJCQkiYXJjaGl0ZWN0dXJlIjogIlNDTVBfQVJDSF9YODZfNjQiLAoJCQkic3ViQXJjaGl0ZWN0dXJlcyI6IFsKCQkJCSJTQ01QX0FSQ0hfWDg2IiwKCQkJCSJTQ01QX0FSQ0hfWDMyIgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX0FBUkNINjQiLAoJCQkic3ViQXJjaGl0ZWN0dXJlcyI6IFsKCQkJCSJTQ01QX0FSQ0hfQVJNIgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX01JUFM2NCIsCgkJCSJzdWJBcmNoaXRlY3R1cmVzIjogWwoJCQkJIlNDTVBfQVJDSF9NSVBTIiwKCQkJCSJTQ01QX0FSQ0hfTUlQUzY0TjMyIgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX01JUFM2NE4zMiIsCgkJCSJzdWJBcmNoaXRlY3R1cmVzIjogWwoJCQkJIlNDTVBfQVJDSF9NSVBTIiwKCQkJCSJTQ01QX0FSQ0hfTUlQUzY0IgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX01JUFNFTDY0IiwKCQkJInN1YkFyY2hpdGVjdHVyZXMiOiBbCgkJCQkiU0NNUF9BUkNIX01JUFNFTCIsCgkJCQkiU0NNUF9BUkNIX01JUFNFTDY0TjMyIgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX01JUFNFTDY0TjMyIiwKCQkJInN1YkFyY2hpdGVjdHVyZXMiOiBbCgkJCQkiU0NNUF9BUkNIX01JUFNFTCIsCgkJCQkiU0NNUF9BUkNIX01JUFNFTDY0IgoJCQldCgkJfSwKCQl7CgkJCSJhcmNoaXRlY3R1cmUiOiAiU0NNUF9BUkNIX1MzOTBYIiwKCQkJInN1YkFyY2hpdGVjdHVyZXMiOiBbCgkJCQkiU0NNUF9BUkNIX1MzOTAiCgkJCV0KCQl9CgldLAoJInN5c2NhbGxzIjogWwoJCXsKCQkJIm5hbWVzIjogWwoJCQkJImFjY2VwdCIsCgkJCQkiYWNjZXB0NCIsCgkJCQkiYWNjZXNzIiwKCQkJCSJhZGp0aW1leCIsCgkJCQkiYWxhcm0iLAoJCQkJImJpbmQiLAoJCQkJImJyayIsCgkJCQkiY2FwZ2V0IiwKCQkJCSJjaGRpciIsCgkJCQkiY2htb2QiLAoJCQkJImNsb2NrX2FkanRpbWUiLAoJCQkJImNsb2NrX2FkanRpbWU2NCIsCgkJCQkiY2xvY2tfZ2V0cmVzIiwKCQkJCSJjbG9ja19nZXRyZXNfdGltZTY0IiwKCQkJCSJjbG9ja19nZXR0aW1lIiwKCQkJCSJjbG9ja19nZXR0aW1lNjQiLAoJCQkJImNsb2NrX25hbm9zbGVlcCIsCgkJCQkiY2xvY2tfbmFub3NsZWVwX3RpbWU2NCIsCgkJCQkiY2xvc2UiLAoJCQkJImNsb3NlX3JhbmdlIiwKCQkJCSJjb25uZWN0IiwKCQkJCSJjb3B5X2ZpbGVfcmFuZ2UiLAoJCQkJImNyZWF0IiwKCQkJCSJkdXAiLAoJCQkJImR1cDIiLAoJCQkJImR1cDMiLAoJCQkJImVwb2xsX2NyZWF0ZSIsCgkJCQkiZXBvbGxfY3JlYXRlMSIsCgkJCQkiZXBvbGxfY3RsIiwKCQkJCSJlcG9sbF9jdGxfb2xkIiwKCQkJCSJlcG9sbF9wd2FpdCIsCgkJCQkiZXBvbGxfcHdhaXQyIiwKCQkJCSJlcG9sbF93YWl0IiwKCQkJCSJlcG9sbF93YWl0X29sZCIsCgkJCQkiZXZlbnRmZCIsCgkJCQkiZXZlbnRmZDIiLAoJCQkJImV4ZWN2ZSIsCgkJCQkiZXhlY3ZlYXQiLAoJCQkJImV4aXQiLAoJCQkJImV4aXRfZ3JvdXAiLAoJCQkJImZhY2Nlc3NhdCIsCgkJCQkiZmFjY2Vzc2F0MiIsCgkJCQkiZmFkdmlzZTY0IiwKCQkJCSJmYWR2aXNlNjRfNjQiLAoJCQkJImZhbGxvY2F0ZSIsCgkJCQkiZmFub3RpZnlfbWFyayIsCgkJCQkiZmNoZGlyIiwKCQkJCSJmY2htb2QiLAoJCQkJImZjaG1vZGF0IiwKCQkJCSJmY2hvd24iLAoJCQkJImZjaG93bjMyIiwKCQkJCSJmY2hvd25hdCIsCgkJCQkiZmNudGwiLAoJCQkJImZjbnRsNjQiLAoJCQkJImZkYXRhc3luYyIsCgkJCQkiZmdldHhhdHRyIiwKCQkJCSJmbGlzdHhhdHRyIiwKCQkJCSJmbG9jayIsCgkJCQkiZm9yayIsCgkJCQkiZnJlbW92ZXhhdHRyIiwKCQkJCSJmc2V0eGF0dHIiLAoJCQkJImZzdGF0IiwKCQkJCSJmc3RhdDY0IiwKCQkJCSJmc3RhdGF0NjQiLAoJCQkJImZzdGF0ZnMiLAoJCQkJImZzdGF0ZnM2NCIsCgkJCQkiZnN5bmMiLAoJCQkJImZ0cnVuY2F0ZSIsCgkJCQkiZnRydW5jYXRlNjQiLAoJCQkJImZ1dGV4IiwKCQkJCSJmdXRleF90aW1lNjQiLAoJCQkJImZ1dGltZXNhdCIsCgkJCQkiZ2V0Y3B1IiwKCQkJCSJnZXRjd2QiLAoJCQkJImdldGRlbnRzIiwKCQkJCSJnZXRkZW50czY0IiwKCQkJCSJnZXRlZ2lkIiwKCQkJCSJnZXRlZ2lkMzIiLAoJCQkJImdldGV1aWQiLAoJCQkJImdldGV1aWQzMiIsCgkJCQkiZ2V0Z2lkIiwKCQkJCSJnZXRnaWQzMiIsCgkJCQkiZ2V0Z3JvdXBzIiwKCQkJCSJnZXRncm91cHMzMiIsCgkJCQkiZ2V0aXRpbWVyIiwKCQkJCSJnZXRwZWVybmFtZSIsCgkJCQkiZ2V0cGdpZCIsCgkJCQkiZ2V0cGdycCIsCgkJCQkiZ2V0cGlkIiwKCQkJCSJnZXRwcGlkIiwKCQkJCSJnZXRwcmlvcml0eSIsCgkJCQkiZ2V0cmFuZG9tIiwKCQkJCSJnZXRyZXNnaWQiLAoJCQkJImdldHJlc2dpZDMyIiwKCQkJCSJnZXRyZXN1aWQiLAoJCQkJImdldHJlc3VpZDMyIiwKCQkJCSJnZXRybGltaXQiLAoJCQkJImdldF9yb2J1c3RfbGlzdCIsCgkJCQkiZ2V0cnVzYWdlIiwKCQkJCSJnZXRzaWQiLAoJCQkJImdldHNvY2tuYW1lIiwKCQkJCSJnZXRzb2Nrb3B0IiwKCQkJCSJnZXRfdGhyZWFkX2FyZWEiLAoJCQkJImdldHRpZCIsCgkJCQkiZ2V0dGltZW9mZGF5IiwKCQkJCSJnZXR1aWQiLAoJCQkJImdldHVpZDMyIiwKCQkJCSJnZXR4YXR0ciIsCgkJCQkiaW5vdGlmeV9hZGRfd2F0Y2giLAoJCQkJImlub3RpZnlfaW5pdCIsCgkJCQkiaW5vdGlmeV9pbml0MSIsCgkJCQkiaW5vdGlmeV9ybV93YXRjaCIsCgkJCQkiaW9fY2FuY2VsIiwKCQkJCSJpb2N0bCIsCgkJCQkiaW9fZGVzdHJveSIsCgkJCQkiaW9fZ2V0ZXZlbnRzIiwKCQkJCSJpb19wZ2V0ZXZlbnRzIiwKCQkJCSJpb19wZ2V0ZXZlbnRzX3RpbWU2NCIsCgkJCQkiaW9wcmlvX2dldCIsCgkJCQkiaW9wcmlvX3NldCIsCgkJCQkiaW9fc2V0dXAiLAoJCQkJImlvX3N1Ym1pdCIsCgkJCQkiaW9fdXJpbmdfZW50ZXIiLAoJCQkJImlvX3VyaW5nX3JlZ2lzdGVyIiwKCQkJCSJpb191cmluZ19zZXR1cCIsCgkJCQkiaXBjIiwKCQkJCSJraWxsIiwKCQkJCSJsY2hvd24iLAoJCQkJImxjaG93bjMyIiwKCQkJCSJsZ2V0eGF0dHIiLAoJCQkJImxpbmsiLAoJCQkJImxpbmthdCIsCgkJCQkibGlzdGVuIiwKCQkJCSJsaXN0eGF0dHIiLAoJCQkJImxsaXN0eGF0dHIiLAoJCQkJIl9sbHNlZWsiLAoJCQkJImxyZW1vdmV4YXR0ciIsCgkJCQkibHNlZWsiLAoJCQkJImxzZXR4YXR0ciIsCgkJCQkibHN0YXQiLAoJCQkJImxzdGF0NjQiLAoJCQkJIm1hZHZpc2UiLAoJCQkJIm1lbWJhcnJpZXIiLAoJCQkJIm1lbWZkX2NyZWF0ZSIsCgkJCQkibWluY29yZSIsCgkJCQkibWtkaXIiLAoJCQkJIm1rZGlyYXQiLAoJCQkJIm1rbm9kIiwKCQkJCSJta25vZGF0IiwKCQkJCSJtbG9jayIsCgkJCQkibWxvY2syIiwKCQkJCSJtbG9ja2FsbCIsCgkJCQkibW1hcCIsCgkJCQkibW1hcDIiLAoJCQkJIm1wcm90ZWN0IiwKCQkJCSJtcV9nZXRzZXRhdHRyIiwKCQkJCSJtcV9ub3RpZnkiLAoJCQkJIm1xX29wZW4iLAoJCQkJIm1xX3RpbWVkcmVjZWl2ZSIsCgkJCQkibXFfdGltZWRyZWNlaXZlX3RpbWU2NCIsCgkJCQkibXFfdGltZWRzZW5kIiwKCQkJCSJtcV90aW1lZHNlbmRfdGltZTY0IiwKCQkJCSJtcV91bmxpbmsiLAoJCQkJIm1yZW1hcCIsCgkJCQkibXNnY3RsIiwKCQkJCSJtc2dnZXQiLAoJCQkJIm1zZ3JjdiIsCgkJCQkibXNnc25kIiwKCQkJCSJtc3luYyIsCgkJCQkibXVubG9jayIsCgkJCQkibXVubG9ja2FsbCIsCgkJCQkibXVubWFwIiwKCQkJCSJuYW5vc2xlZXAiLAoJCQkJIm5ld2ZzdGF0YXQiLAoJCQkJIl9uZXdzZWxlY3QiLAoJCQkJIm9wZW4iLAoJCQkJIm9wZW5hdCIsCgkJCQkib3BlbmF0MiIsCgkJCQkicGF1c2UiLAoJCQkJInBpZGZkX29wZW4iLAoJCQkJInBpZGZkX3NlbmRfc2lnbmFsIiwKCQkJCSJwaXBlIiwKCQkJCSJwaXBlMiIsCgkJCQkicG9sbCIsCgkJCQkicHBvbGwiLAoJCQkJInBwb2xsX3RpbWU2NCIsCgkJCQkicHJjdGwiLAoJCQkJInByZWFkNjQiLAoJCQkJInByZWFkdiIsCgkJCQkicHJlYWR2MiIsCgkJCQkicHJsaW1pdDY0IiwKCQkJCSJwc2VsZWN0NiIsCgkJCQkicHNlbGVjdDZfdGltZTY0IiwKCQkJCSJwd3JpdGU2NCIsCgkJCQkicHdyaXRldiIsCgkJCQkicHdyaXRldjIiLAoJCQkJInJlYWQiLAoJCQkJInJlYWRhaGVhZCIsCgkJCQkicmVhZGxpbmsiLAoJCQkJInJlYWRsaW5rYXQiLAoJCQkJInJlYWR2IiwKCQkJCSJyZWN2IiwKCQkJCSJyZWN2ZnJvbSIsCgkJCQkicmVjdm1tc2ciLAoJCQkJInJlY3ZtbXNnX3RpbWU2NCIsCgkJCQkicmVjdm1zZyIsCgkJCQkicmVtYXBfZmlsZV9wYWdlcyIsCgkJCQkicmVtb3ZleGF0dHIiLAoJCQkJInJlbmFtZSIsCgkJCQkicmVuYW1lYXQiLAoJCQkJInJlbmFtZWF0MiIsCgkJCQkicmVzdGFydF9zeXNjYWxsIiwKCQkJCSJybWRpciIsCgkJCQkicnNlcSIsCgkJCQkicnRfc2lnYWN0aW9uIiwKCQkJCSJydF9zaWdwZW5kaW5nIiwKCQkJCSJydF9zaWdwcm9jbWFzayIsCgkJCQkicnRfc2lncXVldWVpbmZvIiwKCQkJCSJydF9zaWdyZXR1cm4iLAoJCQkJInJ0X3NpZ3N1c3BlbmQiLAoJCQkJInJ0X3NpZ3RpbWVkd2FpdCIsCgkJCQkicnRfc2lndGltZWR3YWl0X3RpbWU2NCIsCgkJCQkicnRfdGdzaWdxdWV1ZWluZm8iLAoJCQkJInNjaGVkX2dldGFmZmluaXR5IiwKCQkJCSJzY2hlZF9nZXRhdHRyIiwKCQkJCSJzY2hlZF9nZXRwYXJhbSIsCgkJCQkic2NoZWRfZ2V0X3ByaW9yaXR5X21heCIsCgkJCQkic2NoZWRfZ2V0X3ByaW9yaXR5X21pbiIsCgkJCQkic2NoZWRfZ2V0c2NoZWR1bGVyIiwKCQkJCSJzY2hlZF9ycl9nZXRfaW50ZXJ2YWwiLAoJCQkJInNjaGVkX3JyX2dldF9pbnRlcnZhbF90aW1lNjQiLAoJCQkJInNjaGVkX3NldGFmZmluaXR5IiwKCQkJCSJzY2hlZF9zZXRhdHRyIiwKCQkJCSJzY2hlZF9zZXRwYXJhbSIsCgkJCQkic2NoZWRfc2V0c2NoZWR1bGVyIiwKCQkJCSJzY2hlZF95aWVsZCIsCgkJCQkic2VsZWN0IiwKCQkJCSJzZW1jdGwiLAoJCQkJInNlbWdldCIsCgkJCQkic2Vtb3AiLAoJCQkJInNlbXRpbWVkb3AiLAoJCQkJInNlbXRpbWVkb3BfdGltZTY0IiwKCQkJCSJzZW5kIiwKCQkJCSJzZW5kZmlsZSIsCgkJCQkic2VuZGZpbGU2NCIsCgkJCQkic2VuZG1tc2ciLAoJCQkJInNlbmRtc2ciLAoJCQkJInNlbmR0byIsCgkJCQkic2V0aXRpbWVyIiwKCQkJCSJzZXRwcmlvcml0eSIsCgkJCQkic2V0X3JvYnVzdF9saXN0IiwKCQkJCSJzZXRzaWQiLAoJCQkJInNldHNvY2tvcHQiLAoJCQkJInNldF90aHJlYWRfYXJlYSIsCgkJCQkic2V0X3RpZF9hZGRyZXNzIiwKCQkJCSJzZXR4YXR0ciIsCgkJCQkic2htYXQiLAoJCQkJInNobWN0bCIsCgkJCQkic2htZHQiLAoJCQkJInNobWdldCIsCgkJCQkic2h1dGRvd24iLAoJCQkJInNpZ2FsdHN0YWNrIiwKCQkJCSJzaWduYWxmZCIsCgkJCQkic2lnbmFsZmQ0IiwKCQkJCSJzaWdwcm9jbWFzayIsCgkJCQkic2lncmV0dXJuIiwKCQkJCSJzcGxpY2UiLAoJCQkJInN0YXQiLAoJCQkJInN0YXQ2NCIsCgkJCQkic3RhdGZzIiwKCQkJCSJzdGF0ZnM2NCIsCgkJCQkic3RhdHgiLAoJCQkJInN5bWxpbmsiLAoJCQkJInN5bWxpbmthdCIsCgkJCQkic3luYyIsCgkJCQkic3luY19maWxlX3JhbmdlIiwKCQkJCSJzeW5jZnMiLAoJCQkJInN5c2luZm8iLAoJCQkJInRlZSIsCgkJCQkidGdraWxsIiwKCQkJCSJ0aW1lIiwKCQkJCSJ0aW1lcl9jcmVhdGUiLAoJCQkJInRpbWVyX2RlbGV0ZSIsCgkJCQkidGltZXJfZ2V0b3ZlcnJ1biIsCgkJCQkidGltZXJfZ2V0dGltZSIsCgkJCQkidGltZXJfZ2V0dGltZTY0IiwKCQkJCSJ0aW1lcl9zZXR0aW1lIiwKCQkJCSJ0aW1lcl9zZXR0aW1lNjQiLAoJCQkJInRpbWVyZmRfY3JlYXRlIiwKCQkJCSJ0aW1lcmZkX2dldHRpbWUiLAoJCQkJInRpbWVyZmRfZ2V0dGltZTY0IiwKCQkJCSJ0aW1lcmZkX3NldHRpbWUiLAoJCQkJInRpbWVyZmRfc2V0dGltZTY0IiwKCQkJCSJ0aW1lcyIsCgkJCQkidGtpbGwiLAoJCQkJInRydW5jYXRlIiwKCQkJCSJ0cnVuY2F0ZTY0IiwKCQkJCSJ1Z2V0cmxpbWl0IiwKCQkJCSJ1bWFzayIsCgkJCQkidW5hbWUiLAoJCQkJInVubGluayIsCgkJCQkidW5saW5rYXQiLAoJCQkJInV0aW1lIiwKCQkJCSJ1dGltZW5zYXQiLAoJCQkJInV0aW1lbnNhdF90aW1lNjQiLAoJCQkJInV0aW1lcyIsCgkJCQkidmZvcmsiLAoJCQkJInZtc3BsaWNlIiwKCQkJCSJ3YWl0NCIsCgkJCQkid2FpdGlkIiwKCQkJCSJ3YWl0cGlkIiwKCQkJCSJ3cml0ZSIsCgkJCQkid3JpdGV2IgoJCQldLAoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIgoJCX0sCgkJewoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCIsCgkJCSJhcmdzIjogWwoJCQkJewoJCQkJCSJpbmRleCI6IDAsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDIKCQkJCX0sCgkJCQl7CgkJCQkJImluZGV4IjogMSwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMQoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAwCgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19OT05CTE9DSywgMCIsCgkJCSJhcmdzIjogWwoJCQkJewoJCQkJCSJpbmRleCI6IDAsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDIKCQkJCX0sCgkJCQl7CgkJCQkJImluZGV4IjogMSwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMjA0OQoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAwCgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19DTE9FWEVDLCAwIiwKCQkJImFyZ3MiOiBbCgkJCQl7CgkJCQkJImluZGV4IjogMCwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMgoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAxLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiA1MjQyODkKCQkJCX0sCgkJCQl7CgkJCQkJImluZGV4IjogMiwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMAoJCQkJfQoKCQkJXQoJCX0sCgkJewoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0sgfCBTT0NLX0NMT0VYRUMsIDAiLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAyCgkJCQl9LAoJCQkJewoJCQkJCSJpbmRleCI6IDEsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDUyNjMzNwoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAwCgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNLCBJUFBST1RPX1RDUCIsCgkJCSJhcmdzIjogWwoJCQkJewoJCQkJCSJpbmRleCI6IDAsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDIKCQkJCX0sCgkJCQl7CgkJCQkJImluZGV4IjogMSwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMQoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiA2CgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19OT05CTE9DSywgSVBQUk9UT19UQ1AiLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAyCgkJCQl9LAoJCQkJewoJCQkJCSJpbmRleCI6IDEsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDIwNDkKCQkJCX0sCgkJCQl7CgkJCQkJImluZGV4IjogMiwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogNgoJCQkJfQoKCQkJXQoJCX0sCgkJewoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfQ0xPRVhFQywgSVBQUk9UT19UQ1AiLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAyCgkJCQl9LAoJCQkJewoJCQkJCSJpbmRleCI6IDEsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDUyNDI4OQoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiA2CgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19OT05CTE9DSyB8IFNPQ0tfQ0xPRVhFQywgSVBQUk9UT19UQ1AiLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAyCgkJCQl9LAoJCQkJewoJCQkJCSJpbmRleCI6IDEsCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsCgkJCQkJInZhbHVlIiA6IDUyNjMzNwoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiA2CgkJCQl9CgoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsgInNvY2tldHBhaXIiIF0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiY29tbWVudCI6ICJBRl9VTklYLCAqLCAwIiwKCQkJImFyZ3MiOiBbCgkJCQl7CgkJCQkJImluZGV4IjogMCwKCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwKCQkJCQkidmFsdWUiIDogMQoJCQkJfSwKCQkJCXsKCQkJCQkiaW5kZXgiOiAyLAoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLAoJCQkJCSJ2YWx1ZSIgOiAwCgkJCQl9CgkJCV0KCQl9LAoJCXsKCQkJIm5hbWVzIjogWwoJCQkJInByb2Nlc3Nfdm1fcmVhZHYiLAoJCQkJInByb2Nlc3Nfdm1fd3JpdGV2IiwKCQkJCSJwdHJhY2UiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiaW5jbHVkZXMiOiB7CgkJCQkibWluS2VybmVsIjogIjQuOCIKCQkJfQoJCX0sCgkJewoJCQkibmFtZXMiOiBbCgkJCQkicGVyc29uYWxpdHkiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJ2YWx1ZSI6IDAsCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIgoJCQkJfQoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsKCQkJCSJwZXJzb25hbGl0eSIKCQkJXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJhcmdzIjogWwoJCQkJewoJCQkJCSJpbmRleCI6IDAsCgkJCQkJInZhbHVlIjogOCwKCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiCgkJCQl9CgkJCV0KCQl9LAoJCXsKCQkJIm5hbWVzIjogWwoJCQkJInBlcnNvbmFsaXR5IgoJCQldLAoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKCQkJImFyZ3MiOiBbCgkJCQl7CgkJCQkJImluZGV4IjogMCwKCQkJCQkidmFsdWUiOiAxMzEwNzIsCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIgoJCQkJfQoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsKCQkJCSJwZXJzb25hbGl0eSIKCQkJXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJhcmdzIjogWwoJCQkJewoJCQkJCSJpbmRleCI6IDAsCgkJCQkJInZhbHVlIjogMTMxMDgwLAoJCQkJCSJvcCI6ICJTQ01QX0NNUF9FUSIKCQkJCX0KCQkJXQoJCX0sCgkJewoJCQkibmFtZXMiOiBbCgkJCQkicGVyc29uYWxpdHkiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAwLAoJCQkJCSJ2YWx1ZSI6IDQyOTQ5NjcyOTUsCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIgoJCQkJfQoJCQldCgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsKCQkJCSJzeW5jX2ZpbGVfcmFuZ2UyIgoJCQldLAoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKCQkJImluY2x1ZGVzIjogewoJCQkJImFyY2hlcyI6IFsKCQkJCQkicHBjNjRsZSIKCQkJCV0KCQkJfQoJCX0sCgkJewoJCQkibmFtZXMiOiBbCgkJCQkiYXJtX2ZhZHZpc2U2NF82NCIsCgkJCQkiYXJtX3N5bmNfZmlsZV9yYW5nZSIsCgkJCQkic3luY19maWxlX3JhbmdlMiIsCgkJCQkiYnJlYWtwb2ludCIsCgkJCQkiY2FjaGVmbHVzaCIsCgkJCQkic2V0X3RscyIKCQkJXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsCgkJCSJpbmNsdWRlcyI6IHsKCQkJCSJhcmNoZXMiOiBbCgkJCQkJImFybSIsCgkJCQkJImFybTY0IgoJCQkJXQoJCQl9CgkJfSwKCQl7CgkJCSJuYW1lcyI6IFsKCQkJCSJhcmNoX3ByY3RsIgoJCQldLAoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKCQkJImluY2x1ZGVzIjogewoJCQkJImFyY2hlcyI6IFsKCQkJCQkiYW1kNjQiLAoJCQkJCSJ4MzIiCgkJCQldCgkJCX0KCQl9LAoJCXsKCQkJIm5hbWVzIjogWwoJCQkJIm1vZGlmeV9sZHQiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiaW5jbHVkZXMiOiB7CgkJCQkiYXJjaGVzIjogWwoJCQkJCSJhbWQ2NCIsCgkJCQkJIngzMiIsCgkJCQkJIng4NiIKCQkJCV0KCQkJfQoJCX0sCgkJewoJCQkibmFtZXMiOiBbCgkJCQkiczM5MF9wY2lfbW1pb19yZWFkIiwKCQkJCSJzMzkwX3BjaV9tbWlvX3dyaXRlIiwKCQkJCSJzMzkwX3J1bnRpbWVfaW5zdHIiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiaW5jbHVkZXMiOiB7CgkJCQkiYXJjaGVzIjogWwoJCQkJCSJzMzkwIiwKCQkJCQkiczM5MHgiCgkJCQldCgkJCX0KCQl9LAoJCXsKCQkJIm5hbWVzIjogWwoJCQkJImNsb25lIgoJCQldLAoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKCQkJImFyZ3MiOiBbCgkJCQl7CgkJCQkJImluZGV4IjogMCwKCQkJCQkidmFsdWUiOiAyMTE0MDYwMjg4LAoJCQkJCSJvcCI6ICJTQ01QX0NNUF9NQVNLRURfRVEiCgkJCQl9CgkJCV0sCgkJCSJleGNsdWRlcyI6IHsKCQkJCSJjYXBzIjogWwoJCQkJCSJDQVBfU1lTX0FETUlOIgoJCQkJXSwKCQkJCSJhcmNoZXMiOiBbCgkJCQkJInMzOTAiLAoJCQkJCSJzMzkweCIKCQkJCV0KCQkJfQoJCX0sCgkJewoJCQkibmFtZXMiOiBbCgkJCQkiY2xvbmUiCgkJCV0sCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLAoJCQkiYXJncyI6IFsKCQkJCXsKCQkJCQkiaW5kZXgiOiAxLAoJCQkJCSJ2YWx1ZSI6IDIxMTQwNjAyODgsCgkJCQkJIm9wIjogIlNDTVBfQ01QX01BU0tFRF9FUSIKCQkJCX0KCQkJXSwKCQkJImNvbW1lbnQiOiAiczM5MCBwYXJhbWV0ZXIgb3JkZXJpbmcgZm9yIGNsb25lIGlzIGRpZmZlcmVudCIsCgkJCSJpbmNsdWRlcyI6IHsKCQkJCSJhcmNoZXMiOiBbCgkJCQkJInMzOTAiLAoJCQkJCSJzMzkweCIKCQkJCV0KCQkJfSwKCQkJImV4Y2x1ZGVzIjogewoJCQkJImNhcHMiOiBbCgkJCQkJIkNBUF9TWVNfQURNSU4iCgkJCQldCgkJCX0KCQl9LAoJCXsKCQkJIm5hbWVzIjogWwoJCQkJImNsb25lMyIKCQkJXSwKCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9FUlJOTyIsCgkJCSJlcnJub1JldCI6IDM4LAoJCQkiZXhjbHVkZXMiOiB7CgkJCQkiY2FwcyI6IFsKCQkJCQkiQ0FQX1NZU19BRE1JTiIKCQkJCV0KCQkJfQoJCX0KCV0KfQo=" + cls.aci_arm_policy = load_policy_from_arm_template_str(cls.custom_arm_json, "")[ + 0 + ] + cls.aci_arm_policy.populate_policy_content_for_all_images() + + cls.aci_arm_policy2 = load_policy_from_arm_template_str(cls.custom_arm_json2.replace("seccompStr", seccomp_profile_contents), "")[ + 0 + ] + cls.aci_arm_policy2.populate_policy_content_for_all_images() + + cls.aci_arm_policy3 = load_policy_from_arm_template_str(cls.custom_arm_json3, "")[ + 0 + ] + cls.aci_arm_policy3.populate_policy_content_for_all_images() + + cls.aci_arm_policy4 = load_policy_from_arm_template_str(cls.custom_arm_json4, "")[ + 0 + ] + cls.aci_arm_policy4.populate_policy_content_for_all_images() + + + def test_arm_template_security_context_defaults(self): + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "", + "strategy": "any" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }""") + + regular_image_json = json.loads( + self.aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertTrue(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_NO_NEW_PRIVILEGES]) + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], "") + # check all the default unprivileged capabilities are present + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_UNPRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING], ignore_order=True), {}) + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_UNPRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE], ignore_order=True), {}) + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_UNPRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED], ignore_order=True), {}) + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT]) + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE]) + # check default pause container + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_CONTAINERS[0], regular_image_json[1], ignore_order=True), {}) + + def test_arm_template_security_context_allow_privilege_escalation(self): + regular_image_json = json.loads( + self.aci_arm_policy3.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + # value of NO_NEW_PRIVILEGES should be the opposite of allowPrivilegeEscalation + self.assertFalse(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_NO_NEW_PRIVILEGES]) + + def test_arm_template_security_context_user(self): + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "456", + "strategy": "id" + }, + "group_idnames": [ + { + "pattern": "123", + "strategy": "id" + } + ], + "umask": "0022" + }""") + + regular_image_json = json.loads( + self.aci_arm_policy2.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + def test_arm_template_security_context_seccomp_profile(self): + expected_seccomp_profile_sha256 = "aeb9bbbd14679be3aab28c35960e2a398e4ce838a066ce2dd5645c4b8da8de21" + + regular_image_json = json.loads( + self.aci_arm_policy2.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], expected_seccomp_profile_sha256) + + def test_arm_template_capabilities_unprivileged_and_not_allow_elevated(self): + attempted_new_capabilities = ["CAP_SYS_TIME", "CAP_DAC_READ_SEARCH"] + attempted_removed_capabilities = ["CAP_CHOWN", "CAP_KILL"] + regular_image_json = json.loads( + self.aci_arm_policy4.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + # ambient & inheritable should still be empty + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT]) + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE]) + for cap in attempted_new_capabilities: + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED]) + for cap in attempted_removed_capabilities: + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING]) + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE]) + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED]) + + def test_arm_template_capabilities_unprivileged_and_allow_elevated(self): + expected_new_capabilities = ["CAP_SYS_TIME", "CAP_DAC_READ_SEARCH"] + expected_removed_capabilities = ["CAP_CHOWN", "CAP_KILL"] + regular_image_json = json.loads( + self.aci_arm_policy2.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + # ambient should be empty + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT]) + for cap in expected_new_capabilities: + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING]) + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE]) + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE]) + self.assertIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED]) + for cap in expected_removed_capabilities: + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE]) + self.assertNotIn(cap, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED]) + + def test_arm_template_capabilities_privileged(self): + regular_image_json = json.loads( + self.aci_arm_policy3.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + # check all the default unprivileged capabilities are present + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_PRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_BOUNDING], ignore_order=True), {}) + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_PRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_EFFECTIVE], ignore_order=True), {}) + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_PRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_PERMITTED], ignore_order=True), {}) + self.assertEquals([], regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_AMBIENT]) + self.assertEquals(deepdiff.DeepDiff(config.DEFAULT_PRIVILEGED_CAPABILITIES, regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES][config.POLICY_FIELD_CONTAINERS_ELEMENTS_CAPABILITIES_INHERITABLE], ignore_order=True), {}) + +# @unittest.skip("not in use") +@pytest.mark.run(order=17) +class PolicyGeneratingSecurityContextUserEdgeCases(unittest.TestCase): + custom_arm_json = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext":{ + "privileged":"true", + "allowPrivilegeEscalation":"true", + "capabilities":{ + "add":["ADDCAP1","ADDCAP2"], + "drop":["DROPCAP1","DROPCAP2"] + }, + "runAsUser":456 + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + custom_arm_json2 = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext":{ + "privileged":"true", + "allowPrivilegeEscalation":"true", + "capabilities":{ + "add":["ADDCAP1","ADDCAP2"], + "drop":["DROPCAP1","DROPCAP2"] + }, + "runAsGroup":123 + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + custom_arm_json3 = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "temp_image" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext":{ + "privileged":"true", + "allowPrivilegeEscalation":"true", + "capabilities":{ + "add":["ADDCAP1","ADDCAP2"], + "drop":["DROPCAP1","DROPCAP2"] + } + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + + @classmethod + def setUpClass(cls): + cls.aci_arm_policy = load_policy_from_arm_template_str(cls.custom_arm_json, "")[ + 0 + ] + cls.aci_arm_policy.populate_policy_content_for_all_images() + + cls.aci_arm_policy2 = load_policy_from_arm_template_str(cls.custom_arm_json2, "")[ + 0 + ] + cls.aci_arm_policy2.populate_policy_content_for_all_images() + + # create docker file to build and test on + cls.path = os.path.dirname(__file__) + cls.dockerfile_path = os.path.join(cls.path, "./Dockerfile") + cls.dockerfile_path2 = os.path.join(cls.path, "./Dockerfile2.dockerfile") + cls.dockerfile_path3 = os.path.join(cls.path, "./Dockerfile3.dockerfile") + cls.dockerfile_path4 = os.path.join(cls.path, "./Dockerfile4.dockerfile") + cls.dockerfile_path5 = os.path.join(cls.path, "./Dockerfile5.dockerfile") + cls.dockerfile_path6 = os.path.join(cls.path, "./Dockerfile6.dockerfile") + + cls.client = docker.from_env() + + @classmethod + def tearDownClass(cls): + cls.client.close() + + def test_arm_template_security_context_no_run_as_group(self): + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "456", + "strategy": "id" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }""") + + regular_image_json = json.loads( + self.aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + def test_arm_template_security_context_no_run_as_user(self): + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "", + "strategy": "any" + }, + "group_idnames": [ + { + "pattern": "123", + "strategy": "id" + } + ], + "umask": "0022" + }""") + + regular_image_json = json.loads( + self.aci_arm_policy2.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + def test_arm_template_security_context_uid_gid(self): + dockerfile_contents = ["FROM ubuntu\n", "USER 456:123\n"] + + try: + with open(self.dockerfile_path, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image", fileobj=open(self.dockerfile_path, "rb")) + finally: + if os.path.exists(self.dockerfile_path): + os.remove(self.dockerfile_path) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3, "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "456", + "strategy": "id" + }, + "group_idnames": [ + { + "pattern": "123", + "strategy": "id" + } + ], + "umask": "0022" + }""") + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + + def test_arm_template_security_context_user_gid(self): + dockerfile_contents = ["FROM ubuntu\n", "USER test_user:123\n"] + + try: + with open(self.dockerfile_path2, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image2", fileobj=open(self.dockerfile_path2, "rb")) + finally: + if os.path.exists(self.dockerfile_path2): + os.remove(self.dockerfile_path2) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3.replace("temp_image", "temp_image2"), "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "test_user", + "strategy": "name" + }, + "group_idnames": [ + { + "pattern": "123", + "strategy": "id" + } + ], + "umask": "0022" + }""") + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + + def test_arm_template_security_context_user_group(self): + dockerfile_contents = ["FROM ubuntu\n", "USER test_user:test_group\n"] + try: + with open(self.dockerfile_path3, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image3", fileobj=open(self.dockerfile_path3, "rb")) + finally: + if os.path.exists(self.dockerfile_path3): + os.remove(self.dockerfile_path3) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3.replace("temp_image", "temp_image3"), "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "test_user", + "strategy": "name" + }, + "group_idnames": [ + { + "pattern": "test_group", + "strategy": "name" + } + ], + "umask": "0022" + }""") + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + + def test_arm_template_security_context_uid_group(self): + # valid values are "user", "uid", + dockerfile_contents = ["FROM ubuntu\n", "USER 456:test_group\n"] + try: + with open(self.dockerfile_path4, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image4", fileobj=open(self.dockerfile_path4, "rb")) + finally: + if os.path.exists(self.dockerfile_path4): + os.remove(self.dockerfile_path4) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3.replace("temp_image", "temp_image4"), "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "456", + "strategy": "id" + }, + "group_idnames": [ + { + "pattern": "test_group", + "strategy": "name" + } + ], + "umask": "0022" + }""") + + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + + def test_arm_template_security_context_uid(self): + dockerfile_contents = ["FROM ubuntu\n", "USER 456\n"] + try: + with open(self.dockerfile_path5, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image5", fileobj=open(self.dockerfile_path5, "rb")) + finally: + if os.path.exists(self.dockerfile_path5): + os.remove(self.dockerfile_path5) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3.replace("temp_image", "temp_image5"), "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "456", + "strategy": "id" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }""") + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + + def test_arm_template_security_context_user_dockerfile(self): + dockerfile_contents = ["FROM ubuntu\n", "USER test_user\n"] + try: + with open(self.dockerfile_path6, "w") as dockerfile: + dockerfile.writelines(dockerfile_contents) + + # build docker image + image = self.client.images.build(nocache=True, tag="temp_image6", fileobj=open(self.dockerfile_path6, "rb")) + finally: + if os.path.exists(self.dockerfile_path6): + os.remove(self.dockerfile_path6) + + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json3.replace("temp_image", "temp_image6"), "")[0] + aci_arm_policy.populate_policy_content_for_all_images() + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + expected_user_json = json.loads("""{ + "user_idname": + { + "pattern": "test_user", + "strategy": "name" + }, + "group_idnames": [ + { + "pattern": "", + "strategy": "any" + } + ], + "umask": "0022" + }""") + self.assertEqual(deepdiff.DeepDiff(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_USER], expected_user_json, ignore_order=True), {}) + + self.client.images.remove(image[0].attrs.get("Id")) + +# @unittest.skip("not in use") +@pytest.mark.run(order=18) +class PolicyGeneratingSecurityContextSeccompProfileEdgeCases(unittest.TestCase): + custom_arm_json = """ + { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + "image": "python:3.6.14-slim-buster" + }, + + + "parameters": { + "containergroupname": { + "type": "string", + "metadata": { + "description": "Name for the container group" + }, + "defaultValue":"simple-container-group" + }, + + "containername": { + "type": "string", + "metadata": { + "description": "Name for the container" + }, + "defaultValue":"simple-container" + }, + "port": { + "type": "string", + "metadata": { + "description": "Port to open on the container and the public IP address." + }, + "defaultValue": "8080" + }, + "cpuCores": { + "type": "string", + "metadata": { + "description": "The number of CPU cores to allocate to the container." + }, + "defaultValue": "1.0" + }, + "memoryInGb": { + "type": "string", + "metadata": { + "description": "The amount of memory to allocate to the container in gigabytes." + }, + "defaultValue": "1.5" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "name": "[parameters('containergroupname')]", + "type": "Microsoft.ContainerInstance/containerGroups", + "apiVersion": "2022-04-01-preview", + "location": "[parameters('location')]", + "properties": { + "containers": [ + { + "name": "[parameters('containername')]", + + "properties": { + "image": "[variables('image')]", + "securityContext": { + "privileged": "false", + "capabilities":{ + "add": ["CAP_SYS_TIME","CAP_DAC_READ_SEARCH"], + "drop": ["CAP_CHOWN","CAP_KILL"] + }, + "runAsGroup": 123, + "runAsUser": 456, + "seccompProfile": "seccompStr" + }, + "command": [ + "python3" + ], + "ports": [ + { + "port": "[parameters('port')]" + } + ], + "resources": { + "requests": { + "cpu": "[parameters('cpuCores')]", + "memoryInGb": "[parameters('memoryInGb')]" + } + }, + "volumeMounts": [ + { + "name": "filesharevolume", + "mountPath": "/aci/logs", + "readOnly": false + }, + { + "name": "secretvolume", + "mountPath": "/aci/secret", + "readOnly": true + } + ] + } + } + ], + "volumes": [ + { + "name": "filesharevolume", + "azureFile": { + "shareName": "shareName1", + "storageAccountName": "storage-account-name", + "storageAccountKey": "storage-account-key" + } + }, + { + + "name": "secretvolume", + "secret": { + "mysecret1": "secret1", + "mysecret2": "secret2" + } + } + + ], + "osType": "Linux", + "restartPolicy": "OnFailure", + "confidentialComputeProperties": { + "IsolationType": "SevSnp" + }, + "ipAddress": { + "type": "Public", + "ports": [ + { + "protocol": "Tcp", + "port": "[parameters( 'port' )]" + } + ] + } + } + } + ], + "outputs": { + "containerIPv4Address": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containergroupname'))).ipAddress.ip]" + } + } + } + """ + + def test_arm_template_security_context_seccomp_profile_all_fields(self): + seccomp_profile_contents = "ew0KCSJjb21tZW50IjogIkRlZmF1bHQgbW9ieSBzZWNjb21wIHBvbGljeSBjb25maWcgZmlsZSBhdDogaHR0cHM6Ly9naXRodWIuY29tL21vYnkvbW9ieS9ibG9iL21hc3Rlci9wcm9maWxlcy9zZWNjb21wL2RlZmF1bHQuanNvbiIsDQoJImRlZmF1bHRBY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLA0KCSJkZWZhdWx0RXJybm9SZXQiOiAxLA0KCSJhcmNoaXRlY3R1cmVzIjogWyAiU0NNUF9BUkNIX1g4NiIsICJTQ01QX0FSQ0hfUFBDIl0sDQoJImZsYWdzIjogWyAiZmxhZzEiLCAiZmxhZzIiLCAiZmxhZzMiIF0sDQoJImxpc3RlbmVyUGF0aCI6ICIvbGlzdGVuZXIvUGF0aCIsDQoJImxpc3RlbmVyTWV0YWRhdGEiOiAibWV0YWRhdGEiLA0KCSJzeXNjYWxscyI6IFsNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDENCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAwDQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0gfCBTT0NLX05PTkJMT0NLLCAwIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMjA0OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfQ0xPRVhFQywgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNDI4OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0sgfCBTT0NLX0NMT0VYRUMsIDAiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA1MjYzMzcNCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAwDQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0sIElQUFJPVE9fVENQIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0ssIElQUFJPVE9fVENQIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMjA0OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfQ0xPRVhFQywgSVBQUk9UT19UQ1AiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA1MjQyODkNCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA2DQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0gfCBTT0NLX05PTkJMT0NLIHwgU09DS19DTE9FWEVDLCBJUFBST1RPX1RDUCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNjMzNw0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0cGFpciIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfVU5JWCwgKiwgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicHJvY2Vzc192bV9yZWFkdiIsDQoJCQkJInByb2Nlc3Nfdm1fd3JpdGV2IiwNCgkJCQkicHRyYWNlIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJtaW5LZXJuZWwiOiAiNC44Ig0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiAwLA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiA4LA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiAxMzEwNzIsDQoJCQkJCSJvcCI6ICJTQ01QX0NNUF9FUSINCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicGVyc29uYWxpdHkiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJ2YWx1ZSI6IDEzMTA4MCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIg0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJwZXJzb25hbGl0eSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJInZhbHVlIjogNDI5NDk2NzI5NSwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIg0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJzeW5jX2ZpbGVfcmFuZ2UyIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJwcGM2NGxlIg0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJhcm1fZmFkdmlzZTY0XzY0IiwNCgkJCQkiYXJtX3N5bmNfZmlsZV9yYW5nZSIsDQoJCQkJInN5bmNfZmlsZV9yYW5nZTIiLA0KCQkJCSJicmVha3BvaW50IiwNCgkJCQkiY2FjaGVmbHVzaCIsDQoJCQkJInNldF90bHMiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJImFybSIsDQoJCQkJCSJhcm02NCINCgkJCQldDQoJCQl9DQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkiYXJjaF9wcmN0bCINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJpbmNsdWRlcyI6IHsNCgkJCQkiYXJjaGVzIjogWw0KCQkJCQkiYW1kNjQiLA0KCQkJCQkieDMyIg0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJtb2RpZnlfbGR0Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJhbWQ2NCIsDQoJCQkJCSJ4MzIiLA0KCQkJCQkieDg2Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJzMzkwX3BjaV9tbWlvX3JlYWQiLA0KCQkJCSJzMzkwX3BjaV9tbWlvX3dyaXRlIiwNCgkJCQkiczM5MF9ydW50aW1lX2luc3RyIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJzMzkwIiwNCgkJCQkJInMzOTB4Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJjbG9uZSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJInZhbHVlIjogMjExNDA2MDI4OCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX01BU0tFRF9FUSINCgkJCQl9DQoJCQldLA0KCQkJImV4Y2x1ZGVzIjogew0KCQkJCSJjYXBzIjogWw0KCQkJCQkiQ0FQX1NZU19BRE1JTiINCgkJCQldLA0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJzMzkwIiwNCgkJCQkJInMzOTB4Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJjbG9uZSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJInZhbHVlIjogMjExNDA2MDI4OCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX01BU0tFRF9FUSINCgkJCQl9DQoJCQldLA0KCQkJImNvbW1lbnQiOiAiczM5MCBwYXJhbWV0ZXIgb3JkZXJpbmcgZm9yIGNsb25lIGlzIGRpZmZlcmVudCIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJInMzOTAiLA0KCQkJCQkiczM5MHgiDQoJCQkJXQ0KCQkJfSwNCgkJCSJleGNsdWRlcyI6IHsNCgkJCQkiY2FwcyI6IFsNCgkJCQkJIkNBUF9TWVNfQURNSU4iDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJImNsb25lMyINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0VSUk5PIiwNCgkJCSJlcnJub1JldCI6IDM4LA0KCQkJImV4Y2x1ZGVzIjogew0KCQkJCSJjYXBzIjogWw0KCQkJCQkiQ0FQX1NZU19BRE1JTiINCgkJCQldDQoJCQl9DQoJCX0NCgldDQp9" + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json.replace("seccompStr", seccomp_profile_contents), "")[ + 0 + ] + aci_arm_policy.populate_policy_content_for_all_images() + expected_seccomp_profile_sha256 = "fb38009a098475bf3423b00f4f7c30f52a66d455f1ef1dcbe1708ad00f26a8cc" + + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], expected_seccomp_profile_sha256) + + def test_arm_template_security_context_seccomp_profile_missing_default_action(self): + seccomp_profile_contents = "ew0KCSJjb21tZW50IjogIkRlZmF1bHQgbW9ieSBzZWNjb21wIHBvbGljeSBjb25maWcgZmlsZSBhdDogaHR0cHM6Ly9naXRodWIuY29tL21vYnkvbW9ieS9ibG9iL21hc3Rlci9wcm9maWxlcy9zZWNjb21wL2RlZmF1bHQuanNvbiIsDQoJImRlZmF1bHRFcnJub1JldCI6IDEsDQoJInN5c2NhbGxzIjogWw0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0ssIDAiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyMDQ5DQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMA0KCQkJCX0NCg0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19DTE9FWEVDLCAwIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogNTI0Mjg5DQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMA0KCQkJCX0NCg0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19OT05CTE9DSyB8IFNPQ0tfQ0xPRVhFQywgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNjMzNw0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1AiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAxDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogNg0KCQkJCX0NCg0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19OT05CTE9DSywgSVBQUk9UT19UQ1AiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyMDQ5DQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogNg0KCQkJCX0NCg0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXQiIF0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJjb21tZW50IjogIkFGX0lORVQsIFNPQ0tfU1RSRUFNIHwgU09DS19DTE9FWEVDLCBJUFBST1RPX1RDUCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNDI4OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0sgfCBTT0NLX0NMT0VYRUMsIElQUFJPVE9fVENQIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogNTI2MzM3DQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogNg0KCQkJCX0NCg0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbICJzb2NrZXRwYWlyIiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9VTklYLCAqLCAwIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAxDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDIsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMA0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJwcm9jZXNzX3ZtX3JlYWR2IiwNCgkJCQkicHJvY2Vzc192bV93cml0ZXYiLA0KCQkJCSJwdHJhY2UiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJIm1pbktlcm5lbCI6ICI0LjgiDQoJCQl9DQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicGVyc29uYWxpdHkiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJ2YWx1ZSI6IDAsDQoJCQkJCSJvcCI6ICJTQ01QX0NNUF9FUSINCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicGVyc29uYWxpdHkiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJ2YWx1ZSI6IDgsDQoJCQkJCSJvcCI6ICJTQ01QX0NNUF9FUSINCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicGVyc29uYWxpdHkiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJ2YWx1ZSI6IDEzMTA3MiwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIg0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJwZXJzb25hbGl0eSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJInZhbHVlIjogMTMxMDgwLA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiA0Mjk0OTY3Mjk1LA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInN5bmNfZmlsZV9yYW5nZTIiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJInBwYzY0bGUiDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJImFybV9mYWR2aXNlNjRfNjQiLA0KCQkJCSJhcm1fc3luY19maWxlX3JhbmdlIiwNCgkJCQkic3luY19maWxlX3JhbmdlMiIsDQoJCQkJImJyZWFrcG9pbnQiLA0KCQkJCSJjYWNoZWZsdXNoIiwNCgkJCQkic2V0X3RscyINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJpbmNsdWRlcyI6IHsNCgkJCQkiYXJjaGVzIjogWw0KCQkJCQkiYXJtIiwNCgkJCQkJImFybTY0Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJhcmNoX3ByY3RsIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJhbWQ2NCIsDQoJCQkJCSJ4MzIiDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJIm1vZGlmeV9sZHQiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJImFtZDY0IiwNCgkJCQkJIngzMiIsDQoJCQkJCSJ4ODYiDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInMzOTBfcGNpX21taW9fcmVhZCIsDQoJCQkJInMzOTBfcGNpX21taW9fd3JpdGUiLA0KCQkJCSJzMzkwX3J1bnRpbWVfaW5zdHIiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJInMzOTAiLA0KCQkJCQkiczM5MHgiDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJImNsb25lIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiAyMTE0MDYwMjg4LA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfTUFTS0VEX0VRIg0KCQkJCX0NCgkJCV0sDQoJCQkiZXhjbHVkZXMiOiB7DQoJCQkJImNhcHMiOiBbDQoJCQkJCSJDQVBfU1lTX0FETUlOIg0KCQkJCV0sDQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJInMzOTAiLA0KCQkJCQkiczM5MHgiDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJImNsb25lIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkidmFsdWUiOiAyMTE0MDYwMjg4LA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfTUFTS0VEX0VRIg0KCQkJCX0NCgkJCV0sDQoJCQkiY29tbWVudCI6ICJzMzkwIHBhcmFtZXRlciBvcmRlcmluZyBmb3IgY2xvbmUgaXMgZGlmZmVyZW50IiwNCgkJCSJpbmNsdWRlcyI6IHsNCgkJCQkiYXJjaGVzIjogWw0KCQkJCQkiczM5MCIsDQoJCQkJCSJzMzkweCINCgkJCQldDQoJCQl9LA0KCQkJImV4Y2x1ZGVzIjogew0KCQkJCSJjYXBzIjogWw0KCQkJCQkiQ0FQX1NZU19BRE1JTiINCgkJCQldDQoJCQl9DQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkiY2xvbmUzIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLA0KCQkJImVycm5vUmV0IjogMzgsDQoJCQkiZXhjbHVkZXMiOiB7DQoJCQkJImNhcHMiOiBbDQoJCQkJCSJDQVBfU1lTX0FETUlOIg0KCQkJCV0NCgkJCX0NCgkJfQ0KCV0NCn0=" + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json.replace("seccompStr", seccomp_profile_contents), "")[ + 0 + ] + aci_arm_policy.populate_policy_content_for_all_images() + expected_seccomp_profile_sha256 = "fa881ac8600f3b835f7f3b5cb8fb49a5eeab2a3eb335134587dd0e30eb69d353" + + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], expected_seccomp_profile_sha256) + + def test_arm_template_security_context_seccomp_profile_missing_default_errno(self): + seccomp_profile_contents = "ew0KCSJjb21tZW50IjogIkRlZmF1bHQgbW9ieSBzZWNjb21wIHBvbGljeSBjb25maWcgZmlsZSBhdDogaHR0cHM6Ly9naXRodWIuY29tL21vYnkvbW9ieS9ibG9iL21hc3Rlci9wcm9maWxlcy9zZWNjb21wL2RlZmF1bHQuanNvbiIsDQoJImRlZmF1bHRBY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLA0KCSJzeXNjYWxscyI6IFsNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDENCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAwDQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0gfCBTT0NLX05PTkJMT0NLLCAwIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMjA0OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfQ0xPRVhFQywgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNDI4OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0sgfCBTT0NLX0NMT0VYRUMsIDAiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA1MjYzMzcNCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAwDQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0sIElQUFJPVE9fVENQIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfTk9OQkxPQ0ssIElQUFJPVE9fVENQIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiAyDQoJCQkJfSwNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDEsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMjA0OQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0IiBdLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiY29tbWVudCI6ICJBRl9JTkVULCBTT0NLX1NUUkVBTSB8IFNPQ0tfQ0xPRVhFQywgSVBQUk9UT19UQ1AiLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDINCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA1MjQyODkNCgkJCQl9LA0KCQkJCXsNCgkJCQkJImluZGV4IjogMiwNCgkJCQkJIm9wIiA6ICJTQ01QX0NNUF9FUSIsDQoJCQkJCSJ2YWx1ZSIgOiA2DQoJCQkJfQ0KDQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsgInNvY2tldCIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfSU5FVCwgU09DS19TVFJFQU0gfCBTT0NLX05PTkJMT0NLIHwgU09DS19DTE9FWEVDLCBJUFBST1RPX1RDUCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMg0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAxLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDUyNjMzNw0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDYNCgkJCQl9DQoNCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWyAic29ja2V0cGFpciIgXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImNvbW1lbnQiOiAiQUZfVU5JWCwgKiwgMCIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJvcCIgOiAiU0NNUF9DTVBfRVEiLA0KCQkJCQkidmFsdWUiIDogMQ0KCQkJCX0sDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAyLA0KCQkJCQkib3AiIDogIlNDTVBfQ01QX0VRIiwNCgkJCQkJInZhbHVlIiA6IDANCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicHJvY2Vzc192bV9yZWFkdiIsDQoJCQkJInByb2Nlc3Nfdm1fd3JpdGV2IiwNCgkJCQkicHRyYWNlIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJtaW5LZXJuZWwiOiAiNC44Ig0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiAwLA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiA4LA0KCQkJCQkib3AiOiAiU0NNUF9DTVBfRVEiDQoJCQkJfQ0KCQkJXQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJInBlcnNvbmFsaXR5Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImFyZ3MiOiBbDQoJCQkJew0KCQkJCQkiaW5kZXgiOiAwLA0KCQkJCQkidmFsdWUiOiAxMzEwNzIsDQoJCQkJCSJvcCI6ICJTQ01QX0NNUF9FUSINCgkJCQl9DQoJCQldDQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkicGVyc29uYWxpdHkiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiYXJncyI6IFsNCgkJCQl7DQoJCQkJCSJpbmRleCI6IDAsDQoJCQkJCSJ2YWx1ZSI6IDEzMTA4MCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIg0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJwZXJzb25hbGl0eSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJInZhbHVlIjogNDI5NDk2NzI5NSwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX0VRIg0KCQkJCX0NCgkJCV0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJzeW5jX2ZpbGVfcmFuZ2UyIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJwcGM2NGxlIg0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJhcm1fZmFkdmlzZTY0XzY0IiwNCgkJCQkiYXJtX3N5bmNfZmlsZV9yYW5nZSIsDQoJCQkJInN5bmNfZmlsZV9yYW5nZTIiLA0KCQkJCSJicmVha3BvaW50IiwNCgkJCQkiY2FjaGVmbHVzaCIsDQoJCQkJInNldF90bHMiDQoJCQldLA0KCQkJImFjdGlvbiI6ICJTQ01QX0FDVF9BTExPVyIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJImFybSIsDQoJCQkJCSJhcm02NCINCgkJCQldDQoJCQl9DQoJCX0sDQoJCXsNCgkJCSJuYW1lcyI6IFsNCgkJCQkiYXJjaF9wcmN0bCINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJpbmNsdWRlcyI6IHsNCgkJCQkiYXJjaGVzIjogWw0KCQkJCQkiYW1kNjQiLA0KCQkJCQkieDMyIg0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJtb2RpZnlfbGR0Ig0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJhbWQ2NCIsDQoJCQkJCSJ4MzIiLA0KCQkJCQkieDg2Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJzMzkwX3BjaV9tbWlvX3JlYWQiLA0KCQkJCSJzMzkwX3BjaV9tbWlvX3dyaXRlIiwNCgkJCQkiczM5MF9ydW50aW1lX2luc3RyIg0KCQkJXSwNCgkJCSJhY3Rpb24iOiAiU0NNUF9BQ1RfQUxMT1ciLA0KCQkJImluY2x1ZGVzIjogew0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJzMzkwIiwNCgkJCQkJInMzOTB4Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJjbG9uZSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMCwNCgkJCQkJInZhbHVlIjogMjExNDA2MDI4OCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX01BU0tFRF9FUSINCgkJCQl9DQoJCQldLA0KCQkJImV4Y2x1ZGVzIjogew0KCQkJCSJjYXBzIjogWw0KCQkJCQkiQ0FQX1NZU19BRE1JTiINCgkJCQldLA0KCQkJCSJhcmNoZXMiOiBbDQoJCQkJCSJzMzkwIiwNCgkJCQkJInMzOTB4Ig0KCQkJCV0NCgkJCX0NCgkJfSwNCgkJew0KCQkJIm5hbWVzIjogWw0KCQkJCSJjbG9uZSINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwNCgkJCSJhcmdzIjogWw0KCQkJCXsNCgkJCQkJImluZGV4IjogMSwNCgkJCQkJInZhbHVlIjogMjExNDA2MDI4OCwNCgkJCQkJIm9wIjogIlNDTVBfQ01QX01BU0tFRF9FUSINCgkJCQl9DQoJCQldLA0KCQkJImNvbW1lbnQiOiAiczM5MCBwYXJhbWV0ZXIgb3JkZXJpbmcgZm9yIGNsb25lIGlzIGRpZmZlcmVudCIsDQoJCQkiaW5jbHVkZXMiOiB7DQoJCQkJImFyY2hlcyI6IFsNCgkJCQkJInMzOTAiLA0KCQkJCQkiczM5MHgiDQoJCQkJXQ0KCQkJfSwNCgkJCSJleGNsdWRlcyI6IHsNCgkJCQkiY2FwcyI6IFsNCgkJCQkJIkNBUF9TWVNfQURNSU4iDQoJCQkJXQ0KCQkJfQ0KCQl9LA0KCQl7DQoJCQkibmFtZXMiOiBbDQoJCQkJImNsb25lMyINCgkJCV0sDQoJCQkiYWN0aW9uIjogIlNDTVBfQUNUX0VSUk5PIiwNCgkJCSJlcnJub1JldCI6IDM4LA0KCQkJImV4Y2x1ZGVzIjogew0KCQkJCSJjYXBzIjogWw0KCQkJCQkiQ0FQX1NZU19BRE1JTiINCgkJCQldDQoJCQl9DQoJCX0NCgldDQp9" + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json.replace("seccompStr", seccomp_profile_contents), "")[ + 0 + ] + aci_arm_policy.populate_policy_content_for_all_images() + expected_seccomp_profile_sha256 = "7bf01bd03f545de915a4ef29d8a60febfe2ee2ef557240d181460fb9a24aea88" + + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], expected_seccomp_profile_sha256) + + def test_arm_template_security_context_seccomp_profile_missing_syscalls(self): + seccomp_profile_contents = "ew0KCSJjb21tZW50IjogIkRlZmF1bHQgbW9ieSBzZWNjb21wIHBvbGljeSBjb25maWcgZmlsZSBhdDogaHR0cHM6Ly9naXRodWIuY29tL21vYnkvbW9ieS9ibG9iL21hc3Rlci9wcm9maWxlcy9zZWNjb21wL2RlZmF1bHQuanNvbiIsDQoJImRlZmF1bHRBY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLA0KCSJkZWZhdWx0RXJybm9SZXQiOiAxLA0KCSJhcmNoaXRlY3R1cmVzIjogWyAiU0NNUF9BUkNIX1g4NiIsICJTQ01QX0FSQ0hfUFBDIl0sDQoJImZsYWdzIjogWyAiZmxhZzEiLCAiZmxhZzIiLCAiZmxhZzMiIF0sDQoJImxpc3RlbmVyUGF0aCI6ICIvbGlzdGVuZXIvUGF0aCIsDQoJImxpc3RlbmVyTWV0YWRhdGEiOiAibWV0YWRhdGEiDQp9" + aci_arm_policy = load_policy_from_arm_template_str(self.custom_arm_json.replace("seccompStr", seccomp_profile_contents), "")[ + 0 + ] + aci_arm_policy.populate_policy_content_for_all_images() + expected_seccomp_profile_sha256 = "4fef6e87b27dfb72359d960b62948bb2072226b497d8f8164c57d6eeaf108479" + + regular_image_json = json.loads( + aci_arm_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + ) + + self.assertEqual(regular_image_json[0][config.POLICY_FIELD_CONTAINERS_ELEMENTS_SECCOMP_PROFILE_SHA256], expected_seccomp_profile_sha256) \ No newline at end of file diff --git a/src/confcom/azext_confcom/tests/latest/test_confcom_image.py b/src/confcom/azext_confcom/tests/latest/test_confcom_image.py index 425923ef8dd..cff8465da6c 100644 --- a/src/confcom/azext_confcom/tests/latest/test_confcom_image.py +++ b/src/confcom/azext_confcom/tests/latest/test_confcom_image.py @@ -29,11 +29,10 @@ def setUpClass(cls): cls.aci_policy = aci_policy def test_image_policy(self): - expected_policy = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjp0cnVlLCJhbGxvd19zdGRpb19hY2Nlc3MiOnRydWUsImNvbW1hbmQiOlsicHl0aG9uMyJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvYmluOi91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJMQU5HPUMuVVRGLTgiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiR1BHX0tFWT0wRDk2REY0RDQxMTBFNUM0M0ZCRkIxN0YyRDM0N0VBNkFBNjU0MjFEIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9WRVJTSU9OPTMuNi4xNCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJQWVRIT05fUElQX1ZFUlNJT049MjEuMi40IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9HRVRfUElQX1VSTD1odHRwczovL2dpdGh1Yi5jb20vcHlwYS9nZXQtcGlwL3Jhdy9jMjBiMGNmZDY0M2NkNGExOTI0NmNjZjIwNGUyOTk3YWY3MGY2YjIxL3B1YmxpYy9nZXQtcGlwLnB5IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9HRVRfUElQX1NIQTI1Nj1mYTZmM2ZiOTNjY2UyMzRjZDRlOGRkMmJlYjU0YTUxYWI5YzI0NzY1M2I1Mjg1NWE0OGRkNDRlNmIyMWZmMjhiIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiKCg/aSlGQUJSSUMpXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkhPU1ROQU1FPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlQoRSk/TVA9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljUGFja2FnZUZpbGVOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6Ikhvc3RlZFNlcnZpY2VOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0FQSV9WRVJTSU9OPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX0hFQURFUj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9TRVJWRVJfVEhVTUJQUklOVD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlX3Jlc3RhcnRlZF9ieT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwiaWQiOiJweXRob246My42LjE0LXNsaW0tYnVzdGVyIiwibGF5ZXJzIjpbIjI1NGNjODUzZGE2MDgxOTA1YzkxMDljOGI5ZDk5YzlmYjA5ODdiYTFkODhmNzI5MDg4OTAzY2ZmYjgwZjU1ZjEiLCJhNTY4ZjE5MDBiZWQ2MGEwNjQxYjc2Yjk5MWFkNDMxNDQ2ZDljM2EzNDRkN2IyNjFmMTBkZThkOGU3Mzc2M2FjIiwiYzcwYzUzMGU4NDJmNjYyMTViMGJkOTU1ODc3MTU3YmEyNGMzNzk5MzAzNTY3YzNmNTY3M2M0NTY2M2VhNGQxNSIsIjNlODZjM2NjZjE2NDJiZjU4NGRlMzNiNDljNzI0OGY4N2VlY2QwZjZkOGMwODM1M2RhYTM2Y2M3YWQwYTdiNmEiLCIxZTQ2ODRkOGM3Y2FhNzRjNjUyNDE3MmI0ZDVhMTU5YTEwODg3NjEzZWQ3MGYxOGQwYTU1ZDA1YjJhZjYxYWNkIl0sIm1vdW50cyI6W3siZGVzdGluYXRpb24iOiIvZXRjL3Jlc29sdi5jb25mIiwib3B0aW9ucyI6WyJyYmluZCIsInJzaGFyZWQiLCJydyJdLCJzb3VyY2UiOiJzYW5kYm94Oi8vL3RtcC9hdGxhcy9yZXNvbHZjb25mLy4rIiwidHlwZSI6ImJpbmQifV0sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifSx7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbIi9wYXVzZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJQQVRIPS91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpbiIsInJlcXVpcmVkIjp0cnVlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImxheWVycyI6WyIxNmI1MTQwNTdhMDZhZDY2NWY5MmMwMjg2M2FjYTA3NGZkNTk3NmM3NTVkMjZiZmYxNjM2NTI5OTE2OWU4NDE1Il0sIm1vdW50cyI6W10sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii8ifV0KCmFsbG93X3Byb3BlcnRpZXNfYWNjZXNzIDo9IGZhbHNlCmFsbG93X2R1bXBfc3RhY2tzIDo9IGZhbHNlCmFsbG93X3J1bnRpbWVfbG9nZ2luZyA6PSBmYWxzZQphbGxvd19lbnZpcm9ubWVudF92YXJpYWJsZV9kcm9wcGluZyA6PSB0cnVlCmFsbG93X3VuZW5jcnlwdGVkX3NjcmF0Y2ggOj0gZmFsc2UKCgoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" + expected_policy = "cGFja2FnZSBwb2xpY3kKCmltcG9ydCBmdXR1cmUua2V5d29yZHMuZXZlcnkKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKZnJhZ21lbnRzIDo9IFsKICB7CiAgICAiZmVlZCI6ICJtY3IubWljcm9zb2Z0LmNvbS9hY2kvYWNpLWNjLWluZnJhLWZyYWdtZW50IiwKICAgICJpbmNsdWRlcyI6IFsKICAgICAgImNvbnRhaW5lcnMiLAogICAgICAiZnJhZ21lbnRzIgogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOng1MDk6MDpzaGEyNTY6SV9faXVMMjVvWEVWRmRUUF9hQkx4X2VUMVJQSGJDUV9FQ0JRZllacHQ5czo6ZWt1OjEuMy42LjEuNC4xLjMxMS43Ni41OS4xLjMiLAogICAgIm1pbmltdW1fc3ZuIjogIjEiCiAgfQpdCgpjb250YWluZXJzIDo9IFt7ImFsbG93X2VsZXZhdGVkIjpmYWxzZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjYXBhYmlsaXRpZXMiOnsiYW1iaWVudCI6W10sImJvdW5kaW5nIjpbIkNBUF9BVURJVF9XUklURSIsIkNBUF9DSE9XTiIsIkNBUF9EQUNfT1ZFUlJJREUiLCJDQVBfRk9XTkVSIiwiQ0FQX0ZTRVRJRCIsIkNBUF9LSUxMIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9CSU5EX1NFUlZJQ0UiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVEdJRCIsIkNBUF9TRVRQQ0FQIiwiQ0FQX1NFVFVJRCIsIkNBUF9TWVNfQ0hST09UIl0sImVmZmVjdGl2ZSI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJpbmhlcml0YWJsZSI6W10sInBlcm1pdHRlZCI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdfSwiY29tbWFuZCI6WyJweXRob24zIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkxBTkc9Qy5VVEYtOCIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiJHUEdfS0VZPTBEOTZERjRENDExMEU1QzQzRkJGQjE3RjJEMzQ3RUE2QUE2NTQyMUQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX1ZFUlNJT049My42LjE0IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBZVEhPTl9QSVBfVkVSU0lPTj0yMS4yLjQiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9weXBhL2dldC1waXAvcmF3L2MyMGIwY2ZkNjQzY2Q0YTE5MjQ2Y2NmMjA0ZTI5OTdhZjcwZjZiMjEvcHVibGljL2dldC1waXAucHkiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUFlUSE9OX0dFVF9QSVBfU0hBMjU2PWZhNmYzZmI5M2NjZTIzNGNkNGU4ZGQyYmViNTRhNTFhYjljMjQ3NjUzYjUyODU1YTQ4ZGQ0NGU2YjIxZmYyOGIiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifSx7InBhdHRlcm4iOiIoKD9pKUZBQlJJQylfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSE9TVE5BTUU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVChFKT9NUD0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNQYWNrYWdlRmlsZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSG9zdGVkU2VydmljZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6InB5dGhvbjozLjYuMTQtc2xpbS1idXN0ZXIiLCJsYXllcnMiOlsiMjU0Y2M4NTNkYTYwODE5MDVjOTEwOWM4YjlkOTljOWZiMDk4N2JhMWQ4OGY3MjkwODg5MDNjZmZiODBmNTVmMSIsImE1NjhmMTkwMGJlZDYwYTA2NDFiNzZiOTkxYWQ0MzE0NDZkOWMzYTM0NGQ3YjI2MWYxMGRlOGQ4ZTczNzYzYWMiLCJjNzBjNTMwZTg0MmY2NjIxNWIwYmQ5NTU4NzcxNTdiYTI0YzM3OTkzMDM1NjdjM2Y1NjczYzQ1NjYzZWE0ZDE1IiwiM2U4NmMzY2NmMTY0MmJmNTg0ZGUzM2I0OWM3MjQ4Zjg3ZWVjZDBmNmQ4YzA4MzUzZGFhMzZjYzdhZDBhN2I2YSIsIjFlNDY4NGQ4YzdjYWE3NGM2NTI0MTcyYjRkNWExNTlhMTA4ODc2MTNlZDcwZjE4ZDBhNTVkMDViMmFmNjFhY2QiXSwibW91bnRzIjpbeyJkZXN0aW5hdGlvbiI6Ii9ldGMvcmVzb2x2LmNvbmYiLCJvcHRpb25zIjpbInJiaW5kIiwicnNoYXJlZCIsInJ3Il0sInNvdXJjZSI6InNhbmRib3g6Ly8vdG1wL2F0bGFzL3Jlc29sdmNvbmYvLisiLCJ0eXBlIjoiYmluZCJ9XSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn0seyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY2FwYWJpbGl0aWVzIjp7ImFtYmllbnQiOltdLCJib3VuZGluZyI6WyJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZTRVRJRCIsIkNBUF9GT1dORVIiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX1JBVyIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUVUlEIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUUENBUCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX1NZU19DSFJPT1QiLCJDQVBfS0lMTCIsIkNBUF9BVURJVF9XUklURSJdLCJlZmZlY3RpdmUiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXSwiaW5oZXJpdGFibGUiOltdLCJwZXJtaXR0ZWQiOlsiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GU0VUSUQiLCJDQVBfRk9XTkVSIiwiQ0FQX01LTk9EIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFVJRCIsIkNBUF9TRVRGQ0FQIiwiQ0FQX1NFVFBDQVAiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9TWVNfQ0hST09UIiwiQ0FQX0tJTEwiLCJDQVBfQVVESVRfV1JJVEUiXX0sImNvbW1hbmQiOlsiL3BhdXNlIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOnRydWUsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiVEVSTT14dGVybSIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJzdHJpbmcifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwibGF5ZXJzIjpbIjE2YjUxNDA1N2EwNmFkNjY1ZjkyYzAyODYzYWNhMDc0ZmQ1OTc2Yzc1NWQyNmJmZjE2MzY1Mjk5MTY5ZTg0MTUiXSwibW91bnRzIjpbXSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvIn1dCgphbGxvd19wcm9wZXJ0aWVzX2FjY2VzcyA6PSBmYWxzZQphbGxvd19kdW1wX3N0YWNrcyA6PSBmYWxzZQphbGxvd19ydW50aW1lX2xvZ2dpbmcgOj0gZmFsc2UKYWxsb3dfZW52aXJvbm1lbnRfdmFyaWFibGVfZHJvcHBpbmcgOj0gdHJ1ZQphbGxvd191bmVuY3J5cHRlZF9zY3JhdGNoIDo9IGZhbHNlCmFsbG93X2NhcGFiaWxpdHlfZHJvcHBpbmcgOj0gdHJ1ZQoKbW91bnRfZGV2aWNlIDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X2RldmljZQp1bm1vdW50X2RldmljZSA6PSBkYXRhLmZyYW1ld29yay51bm1vdW50X2RldmljZQptb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLm1vdW50X292ZXJsYXkKdW5tb3VudF9vdmVybGF5IDo9IGRhdGEuZnJhbWV3b3JrLnVubW91bnRfb3ZlcmxheQpjcmVhdGVfY29udGFpbmVyIDo9IGRhdGEuZnJhbWV3b3JrLmNyZWF0ZV9jb250YWluZXIKZXhlY19pbl9jb250YWluZXIgOj0gZGF0YS5mcmFtZXdvcmsuZXhlY19pbl9jb250YWluZXIKZXhlY19leHRlcm5hbCA6PSBkYXRhLmZyYW1ld29yay5leGVjX2V4dGVybmFsCnNodXRkb3duX2NvbnRhaW5lciA6PSBkYXRhLmZyYW1ld29yay5zaHV0ZG93bl9jb250YWluZXIKc2lnbmFsX2NvbnRhaW5lcl9wcm9jZXNzIDo9IGRhdGEuZnJhbWV3b3JrLnNpZ25hbF9jb250YWluZXJfcHJvY2VzcwpwbGFuOV9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5wbGFuOV9tb3VudApwbGFuOV91bm1vdW50IDo9IGRhdGEuZnJhbWV3b3JrLnBsYW45X3VubW91bnQKZ2V0X3Byb3BlcnRpZXMgOj0gZGF0YS5mcmFtZXdvcmsuZ2V0X3Byb3BlcnRpZXMKZHVtcF9zdGFja3MgOj0gZGF0YS5mcmFtZXdvcmsuZHVtcF9zdGFja3MKcnVudGltZV9sb2dnaW5nIDo9IGRhdGEuZnJhbWV3b3JrLnJ1bnRpbWVfbG9nZ2luZwpsb2FkX2ZyYWdtZW50IDo9IGRhdGEuZnJhbWV3b3JrLmxvYWRfZnJhZ21lbnQKc2NyYXRjaF9tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX21vdW50CnNjcmF0Y2hfdW5tb3VudCA6PSBkYXRhLmZyYW1ld29yay5zY3JhdGNoX3VubW91bnQKCnJlYXNvbiA6PSB7ImVycm9ycyI6IGRhdGEuZnJhbWV3b3JrLmVycm9yc30=" # deep diff the output policies from the regular policy.json and the ARM template aci_policy_str = self.aci_policy.get_serialized_output() - self.assertEqual(aci_policy_str, expected_policy) @@ -49,9 +48,9 @@ def setUpClass(cls): cls.aci_policy = aci_policy def test_sidecar_image_policy(self): - expected_policy = "cGFja2FnZSBtaWNyb3NvZnRjb250YWluZXJpbnN0YW5jZQoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6dHJ1ZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbIi9tb3VudF9henVyZV9maWxlLnNoIl0sImVudl9ydWxlcyI6W3sicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6Im1jci5taWNyb3NvZnQuY29tL2FjaS9hdGxhcy1tb3VudC1henVyZS1maWxlLXZvbHVtZTptYXN0ZXJfMjAyMDEyMTAuMiIsImxheWVycyI6WyI2MDZmZDZiYWY1ZWIxYTcxZmQyODZhZWEyOTY3MmEwNmJmZTU1ZjAwMDdkZWQ5MmVlNzMxNDJhMzc1OTBlZDE5IiwiM2FkMWEyZmY0YTQ0YmM4NjBiM2NkMDI3Y2M4NmNlNDVhMzk5YzRjOTk1YzM2ZTk4MDBjNTM2OGNiNzI3YTdlMSIsImIxY2ZjMzBmMzdmMDhlNjA2NjhkYjNmNzE2MDY5N2IxOWQyYWQ0NWIxMmYwNzUxODg1Mjk5MzczNjE2YTZlMGEiLCJlZjM2NDg0NmM4ZjFmNDNkMTRkMmUzZTc5MTlhMDY0YjBjODI1NTNjMDhiMzU0MjJmNWQxZjA3YzM0MzViNDYyIiwiNTgyZmUzOWJkMzU5MDliYWY2YzQwMzY3MzRlMjBmNzY2MzkxYmE4MzcyN2ZiMWQ2ODNiZTA0NWZlNDUzYjVhZiIsImFhYzlmYjQwNDI1OGMwNjlhZTg1MzgyMzY0ZjVkMmJhMWQ0MDUxOGM2YjFmNTZhZGU2YmMyMmYzMDI4ZWFmZjAiXSwibW91bnRzIjpbXSwic2lnbmFscyI6W10sIndvcmtpbmdfZGlyIjoiLyJ9XQ==" + expected_policy = "cGFja2FnZSBtaWNyb3NvZnRjb250YWluZXJpbnN0YW5jZQoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY2FwYWJpbGl0aWVzIjp7ImFtYmllbnQiOltdLCJib3VuZGluZyI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJlZmZlY3RpdmUiOlsiQ0FQX0FVRElUX1dSSVRFIiwiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GT1dORVIiLCJDQVBfRlNFVElEIiwiQ0FQX0tJTEwiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFBDQVAiLCJDQVBfU0VUVUlEIiwiQ0FQX1NZU19DSFJPT1QiXSwiaW5oZXJpdGFibGUiOltdLCJwZXJtaXR0ZWQiOlsiQ0FQX0FVRElUX1dSSVRFIiwiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GT1dORVIiLCJDQVBfRlNFVElEIiwiQ0FQX0tJTEwiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFBDQVAiLCJDQVBfU0VUVUlEIiwiQ0FQX1NZU19DSFJPT1QiXX0sImNvbW1hbmQiOlsiL21vdW50X2F6dXJlX2ZpbGUuc2giXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn1dLCJleGVjX3Byb2Nlc3NlcyI6W10sImlkIjoibWNyLm1pY3Jvc29mdC5jb20vYWNpL2F0bGFzLW1vdW50LWF6dXJlLWZpbGUtdm9sdW1lOm1hc3Rlcl8yMDIwMTIxMC4yIiwibGF5ZXJzIjpbIjYwNmZkNmJhZjVlYjFhNzFmZDI4NmFlYTI5NjcyYTA2YmZlNTVmMDAwN2RlZDkyZWU3MzE0MmEzNzU5MGVkMTkiLCIzYWQxYTJmZjRhNDRiYzg2MGIzY2QwMjdjYzg2Y2U0NWEzOTljNGM5OTVjMzZlOTgwMGM1MzY4Y2I3MjdhN2UxIiwiYjFjZmMzMGYzN2YwOGU2MDY2OGRiM2Y3MTYwNjk3YjE5ZDJhZDQ1YjEyZjA3NTE4ODUyOTkzNzM2MTZhNmUwYSIsImVmMzY0ODQ2YzhmMWY0M2QxNGQyZTNlNzkxOWEwNjRiMGM4MjU1M2MwOGIzNTQyMmY1ZDFmMDdjMzQzNWI0NjIiLCI1ODJmZTM5YmQzNTkwOWJhZjZjNDAzNjczNGUyMGY3NjYzOTFiYTgzNzI3ZmIxZDY4M2JlMDQ1ZmU0NTNiNWFmIiwiYWFjOWZiNDA0MjU4YzA2OWFlODUzODIzNjRmNWQyYmExZDQwNTE4YzZiMWY1NmFkZTZiYzIyZjMwMjhlYWZmMCJdLCJtb3VudHMiOltdLCJub19uZXdfcHJpdmlsZWdlcyI6dHJ1ZSwic2VjY29tcF9wcm9maWxlX3NoYTI1NiI6IiIsInNpZ25hbHMiOltdLCJ1c2VyIjp7Imdyb3VwX2lkbmFtZXMiOlt7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9XSwidW1hc2siOiIwMDIyIiwidXNlcl9pZG5hbWUiOnsicGF0dGVybiI6IiIsInN0cmF0ZWd5IjoiYW55In19LCJ3b3JraW5nX2RpciI6Ii8ifV0=" aci_policy_str = self.aci_policy.get_serialized_output() - + self.assertEqual(aci_policy_str, expected_policy) diff --git a/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py b/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py index 26becc9b9a0..49d16ff2332 100644 --- a/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py +++ b/src/confcom/azext_confcom/tests/latest/test_confcom_scenario.py @@ -272,11 +272,12 @@ def setUpClass(cls): cls.aci_policy = aci_policy def test_injected_sidecar_container_msi(self): - expected_sidecar_container_ser = "cGFja2FnZSBtaWNyb3NvZnRjb250YWluZXJpbnN0YW5jZQoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6dHJ1ZSwiYWxsb3dfc3RkaW9fYWNjZXNzIjp0cnVlLCJjb21tYW5kIjpbIi9iaW4vc2giLCItYyIsInVudGlsIC4vbXNpQXRsYXNBZGFwdGVyOyBkbyBlY2hvICQ/IHJlc3RhcnRpbmc7IGRvbmUiXSwiZW52X3J1bGVzIjpbeyJwYXR0ZXJuIjoiSURFTlRJVFlfQVBJX1ZFUlNJT049LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfSEVBREVSPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IklERU5USVRZX1NFUlZFUl9USFVNQlBSSU5UPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkFDSV9NSV9DTElFTlRfSURfLis9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiQUNJX01JX1JFU19JRF8uKz0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJIT1NUTkFNRT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJURVJNPXh0ZXJtIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IigoP2kpRkFCUklDKV8uKz0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNfSWQrPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY19TZXJ2aWNlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNfQXBwbGljYXRpb25OYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY19Db2RlUGFja2FnZU5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljX1NlcnZpY2VEbnNOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkFDSV9NSV9ERUZBVUxUPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlRva2VuUHJveHlJcEFkZHJlc3NFbnZLZXlOYW1lPVtDb250YWluZXJUb0hvc3RBZGRyZXNzfEZhYnJpY19Ob2RlbFBPckZRRE5dIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkNvbnRhaW5lclRvSG9zdEFkZHJlc3M9IiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InN0cmluZyJ9LHsicGF0dGVybiI6IkZhYnJpY19OZXR3b3JraW5nTW9kZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlX3Jlc3RhcnRlZF9ieT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifV0sImV4ZWNfcHJvY2Vzc2VzIjpbXSwiaWQiOiJtY3IubWljcm9zb2Z0LmNvbS9hY2kvbXNpLWF0bGFzLWFkYXB0ZXI6bWFzdGVyXzIwMjAxMjAzLjEiLCJsYXllcnMiOlsiNjA2ZmQ2YmFmNWViMWE3MWZkMjg2YWVhMjk2NzJhMDZiZmU1NWYwMDA3ZGVkOTJlZTczMTQyYTM3NTkwZWQxOSIsIjkwYWQyZjViMmM0MjVhN2M0NThmOWY1ZDIxY2YwNjRjMjE1ZjE0ZTQwNjgwMDk2OGY2NDRkMmFiMGI0ZDA0ZGYiLCIxYzRiNjM2NWE3YjkzODM4N2RmZDgyMjg2MmNhNDFhZTU0OTBiNTQ5MGU0YzI2ZWI0YjVkYTk2YzY0MDk2MGNmIl0sIm1vdW50cyI6W10sInNpZ25hbHMiOltdLCJ3b3JraW5nX2RpciI6Ii9yb290LyJ9XQ==" + expected_sidecar_container_ser = "cGFja2FnZSBtaWNyb3NvZnRjb250YWluZXJpbnN0YW5jZQoKYXBpX3ZlcnNpb24gOj0gIjAuMTAuMCIKZnJhbWV3b3JrX3ZlcnNpb24gOj0gIjAuMi4zIgoKY29udGFpbmVycyA6PSBbeyJhbGxvd19lbGV2YXRlZCI6ZmFsc2UsImFsbG93X3N0ZGlvX2FjY2VzcyI6dHJ1ZSwiY2FwYWJpbGl0aWVzIjp7ImFtYmllbnQiOltdLCJib3VuZGluZyI6WyJDQVBfQVVESVRfV1JJVEUiLCJDQVBfQ0hPV04iLCJDQVBfREFDX09WRVJSSURFIiwiQ0FQX0ZPV05FUiIsIkNBUF9GU0VUSUQiLCJDQVBfS0lMTCIsIkNBUF9NS05PRCIsIkNBUF9ORVRfQklORF9TRVJWSUNFIiwiQ0FQX05FVF9SQVciLCJDQVBfU0VURkNBUCIsIkNBUF9TRVRHSUQiLCJDQVBfU0VUUENBUCIsIkNBUF9TRVRVSUQiLCJDQVBfU1lTX0NIUk9PVCJdLCJlZmZlY3RpdmUiOlsiQ0FQX0FVRElUX1dSSVRFIiwiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GT1dORVIiLCJDQVBfRlNFVElEIiwiQ0FQX0tJTEwiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFBDQVAiLCJDQVBfU0VUVUlEIiwiQ0FQX1NZU19DSFJPT1QiXSwiaW5oZXJpdGFibGUiOltdLCJwZXJtaXR0ZWQiOlsiQ0FQX0FVRElUX1dSSVRFIiwiQ0FQX0NIT1dOIiwiQ0FQX0RBQ19PVkVSUklERSIsIkNBUF9GT1dORVIiLCJDQVBfRlNFVElEIiwiQ0FQX0tJTEwiLCJDQVBfTUtOT0QiLCJDQVBfTkVUX0JJTkRfU0VSVklDRSIsIkNBUF9ORVRfUkFXIiwiQ0FQX1NFVEZDQVAiLCJDQVBfU0VUR0lEIiwiQ0FQX1NFVFBDQVAiLCJDQVBfU0VUVUlEIiwiQ0FQX1NZU19DSFJPT1QiXX0sImNvbW1hbmQiOlsiL2Jpbi9zaCIsIi1jIiwidW50aWwgLi9tc2lBdGxhc0FkYXB0ZXI7IGRvIGVjaG8gJD8gcmVzdGFydGluZzsgZG9uZSJdLCJlbnZfcnVsZXMiOlt7InBhdHRlcm4iOiJJREVOVElUWV9BUElfVkVSU0lPTj0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJJREVOVElUWV9IRUFERVI9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiSURFTlRJVFlfU0VSVkVSX1RIVU1CUFJJTlQ9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiQUNJX01JX0NMSUVOVF9JRF8uKz0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJBQ0lfTUlfUkVTX0lEXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkhPU1ROQU1FPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IlRFUk09eHRlcm0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiKCg/aSlGQUJSSUMpXy4rPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY19JZCs9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljX1NlcnZpY2VOYW1lPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6IkZhYnJpY19BcHBsaWNhdGlvbk5hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiRmFicmljX0NvZGVQYWNrYWdlTmFtZT0uKyIsInJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3kiOiJyZTIifSx7InBhdHRlcm4iOiJGYWJyaWNfU2VydmljZURuc05hbWU9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiQUNJX01JX0RFRkFVTFQ9LisiLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiVG9rZW5Qcm94eUlwQWRkcmVzc0VudktleU5hbWU9W0NvbnRhaW5lclRvSG9zdEFkZHJlc3N8RmFicmljX05vZGVsUE9yRlFETl0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5IjoicmUyIn0seyJwYXR0ZXJuIjoiQ29udGFpbmVyVG9Ib3N0QWRkcmVzcz0iLCJyZXF1aXJlZCI6ZmFsc2UsInN0cmF0ZWd5Ijoic3RyaW5nIn0seyJwYXR0ZXJuIjoiRmFicmljX05ldHdvcmtpbmdNb2RlPS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9LHsicGF0dGVybiI6ImF6dXJlY29udGFpbmVyaW5zdGFuY2VfcmVzdGFydGVkX2J5PS4rIiwicmVxdWlyZWQiOmZhbHNlLCJzdHJhdGVneSI6InJlMiJ9XSwiZXhlY19wcm9jZXNzZXMiOltdLCJpZCI6Im1jci5taWNyb3NvZnQuY29tL2FjaS9tc2ktYXRsYXMtYWRhcHRlcjptYXN0ZXJfMjAyMDEyMDMuMSIsImxheWVycyI6WyI2MDZmZDZiYWY1ZWIxYTcxZmQyODZhZWEyOTY3MmEwNmJmZTU1ZjAwMDdkZWQ5MmVlNzMxNDJhMzc1OTBlZDE5IiwiOTBhZDJmNWIyYzQyNWE3YzQ1OGY5ZjVkMjFjZjA2NGMyMTVmMTRlNDA2ODAwOTY4ZjY0NGQyYWIwYjRkMDRkZiIsIjFjNGI2MzY1YTdiOTM4Mzg3ZGZkODIyODYyY2E0MWFlNTQ5MGI1NDkwZTRjMjZlYjRiNWRhOTZjNjQwOTYwY2YiXSwibW91bnRzIjpbXSwibm9fbmV3X3ByaXZpbGVnZXMiOnRydWUsInNlY2NvbXBfcHJvZmlsZV9zaGEyNTYiOiIiLCJzaWduYWxzIjpbXSwidXNlciI6eyJncm91cF9pZG5hbWVzIjpbeyJwYXR0ZXJuIjoiIiwic3RyYXRlZ3kiOiJhbnkifV0sInVtYXNrIjoiMDAyMiIsInVzZXJfaWRuYW1lIjp7InBhdHRlcm4iOiIiLCJzdHJhdGVneSI6ImFueSJ9fSwid29ya2luZ19kaXIiOiIvcm9vdC8ifV0=" + image = self.aci_policy.get_images()[0] self.assertEqual(image.base, "mcr.microsoft.com/aci/msi-atlas-adapter") self.assertIsNotNone(image) - + self.maxDiff = None expected_workingdir = "/root/" self.assertEqual(image._workingDir, expected_workingdir) @@ -312,7 +313,7 @@ def setUpClass(cls): aci_policy.populate_policy_content_for_all_images() cls.aci_policy = aci_policy - def test_logging_enabled(self): + def test_debug_flags(self): policy = self.aci_policy.get_serialized_output( output_type=OutputType.RAW, rego_boilerplate=True @@ -322,11 +323,17 @@ def test_logging_enabled(self): expected_logging_string = "allow_runtime_logging := true" expected_properties_access = "allow_properties_access := true" expected_dump_stacks = "allow_dump_stacks := true" + expected_env_var_dropping = "allow_environment_variable_dropping := true" + expected_capability_dropping = "allow_capability_dropping := true" + expected_unencrypted_scratch = "allow_unencrypted_scratch := false" # make sure all these are included in the policy self.assertTrue(expected_logging_string in policy) self.assertTrue(expected_properties_access in policy) self.assertTrue(expected_dump_stacks in policy) + self.assertTrue(expected_env_var_dropping in policy) + self.assertTrue(expected_capability_dropping in policy) + self.assertTrue(expected_unencrypted_scratch in policy) # @unittest.skip("not in use") @@ -403,7 +410,7 @@ def test_sidecar_stdio_access_default(self): output_type=OutputType.RAW, rego_boilerplate=False ) )[0][ - config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS + config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS ] ) @@ -658,12 +665,15 @@ def test_stdio_access_default(self): with load_policy_from_str(custom_json) as aci_policy: aci_policy.populate_policy_content_for_all_images() self.assertTrue( - json.loads( - aci_policy.get_serialized_output(output_type=OutputType.RAW, rego_boilerplate=False) - )[0][ - config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS - ] - ) + json.loads( + aci_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + )[0][ + config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS + ] + ) + def test_stdio_access_updated(self): custom_json = """ @@ -683,12 +693,15 @@ def test_stdio_access_updated(self): aci_policy.populate_policy_content_for_all_images() self.assertFalse( - json.loads( - aci_policy.get_serialized_output(output_type=OutputType.RAW, rego_boilerplate=False) - )[0][ - config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS - ] - ) + json.loads( + aci_policy.get_serialized_output( + output_type=OutputType.RAW, rego_boilerplate=False + ) + )[0][ + config.POLICY_FIELD_CONTAINERS_ELEMENTS_ALLOW_STDIO_ACCESS + ] + ) + # @unittest.skip("not in use") @@ -881,3 +894,5 @@ def test_json_missing_command(self): with self.assertRaises(SystemExit) as exc_info: load_policy_from_str(custom_json) self.assertEqual(exc_info.exception.code, 1) + + diff --git a/src/confcom/requirements.txt b/src/confcom/requirements.txt index b7c00f45c15..35b762b9cfc 100644 --- a/src/confcom/requirements.txt +++ b/src/confcom/requirements.txt @@ -1,4 +1,5 @@ docker tqdm azure-devtools -deepdiff \ No newline at end of file +deepdiff +pydash \ No newline at end of file diff --git a/src/confcom/setup.py b/src/confcom/setup.py index 1ebcf7912be..dff0ec65448 100644 --- a/src/confcom/setup.py +++ b/src/confcom/setup.py @@ -17,8 +17,6 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") -# TODO: Confirm this is the right version number you want and it matches your -# HISTORY.rst entry. VERSION = "0.2.14" # The full list of classifiers is available at @@ -37,7 +35,7 @@ "License :: OSI Approved :: MIT License", ] -DEPENDENCIES = ["docker", "tqdm", "deepdiff"] +DEPENDENCIES = ["docker", "tqdm", "deepdiff", "pydash"] SecurityPolicyProxy.download_binaries()