Skip to content

Commit 8910a7d

Browse files
committed
[confcom] Derive image platform and add --platform validation
1 parent b6816c4 commit 8910a7d

1 file changed

Lines changed: 43 additions & 2 deletions

File tree

src/confcom/azext_confcom/security_policy.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from azext_confcom.container import ContainerImage, UserContainerImage
1717
from azext_confcom.errors import eprint
1818
from azext_confcom.fragment_util import sanitize_fragment_fields
19-
from azext_confcom.oras_proxy import create_list_of_standalone_imports
19+
from azext_confcom.oras_proxy import create_list_of_standalone_imports, get_image_platforms
2020
from azext_confcom.rootfs_proxy import SecurityPolicyProxy
2121
from azext_confcom.template_util import (case_insensitive_dict_get,
2222
compare_env_vars,
@@ -41,7 +41,8 @@
4141
process_fragment_imports,
4242
process_mounts,
4343
process_mounts_from_config,
44-
readable_diff)
44+
readable_diff,
45+
find_value_in_params_and_vars)
4546
from azext_confcom.lib.images import get_image_platform # pylint: disable=unused-import
4647
from azext_confcom.lib.defaults import get_debug_mode_exec_procs
4748
from knack.log import get_logger
@@ -669,6 +670,36 @@ def set_images(self, images: List[ContainerImage]) -> None:
669670
self._images = images
670671

671672

673+
def validate_image_platform(image_name: str, platform: str) -> None:
674+
"""Validate that a single-platform image matches the specified platform.
675+
676+
Uses the registry manifest to detect supported platforms. If the image
677+
supports only one platform and it differs from the requested platform,
678+
an error is raised. Multi-platform images and detection failures are
679+
allowed to pass through.
680+
"""
681+
try:
682+
supported = get_image_platforms(image_name)
683+
except Exception: # pylint: disable=broad-except
684+
# If registry detection fails, skip validation gracefully
685+
return
686+
687+
if not supported:
688+
return
689+
690+
if len(supported) == 1 and supported[0] != platform:
691+
eprint(
692+
f'Image "{image_name}" only supports platform "{supported[0]}", '
693+
f'which does not match the specified platform "{platform}".'
694+
)
695+
696+
if len(supported) > 1 and platform not in supported:
697+
eprint(
698+
f'Image "{image_name}" supports platforms {supported}, '
699+
f'which does not include the specified platform "{platform}".'
700+
)
701+
702+
672703
# pylint: disable=R0914,
673704
def load_policy_from_arm_template_str(
674705
template_data: str,
@@ -830,6 +861,10 @@ def load_policy_from_arm_template_str(
830861
f'Field ["{config.ACI_FIELD_TEMPLATE_IMAGE}"] is empty or cannot be found'
831862
)
832863

864+
# Resolve ARM parameters/variables to get the real image name for validation
865+
resolved_image = find_value_in_params_and_vars(all_params, all_vars, image_name)
866+
validate_image_platform(resolved_image, platform)
867+
833868
exec_processes = []
834869
extract_probe(exec_processes, image_properties, config.ACI_FIELD_CONTAINERS_READINESS_PROBE)
835870
extract_probe(exec_processes, image_properties, config.ACI_FIELD_CONTAINERS_LIVENESS_PROBE)
@@ -920,6 +955,8 @@ def load_policy_from_image_name(
920955

921956
containers = []
922957
for image_name in image_names:
958+
validate_image_platform(image_name, platform)
959+
923960
container = {}
924961
# assign just the fields that are expected
925962
# the values will come when calling
@@ -1037,6 +1074,8 @@ def load_policy_from_json(
10371074
f'Field ["{config.ACI_FIELD_TEMPLATE_IMAGE}"] is empty or cannot be found'
10381075
)
10391076

1077+
validate_image_platform(image_name, platform)
1078+
10401079
container_name = case_insensitive_dict_get(
10411080
container, config.ACI_FIELD_CONTAINERS_NAME
10421081
) or image_name
@@ -1250,6 +1289,8 @@ def load_policy_from_virtual_node_yaml_str(
12501289
if not image:
12511290
eprint("Container does not have an image field")
12521291

1292+
validate_image_platform(image, platform)
1293+
12531294
# env vars
12541295
envs = process_env_vars_from_yaml(
12551296
container,

0 commit comments

Comments
 (0)