Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/confcom/azext_confcom/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def acipolicygen_confcom(
# gather information about the fragments being used in the new policy
if include_fragments:
fragments_list = os_util.load_json_from_file(fragments_json or input_path)
fragments_list = fragments_list.get("fragments", []) or fragments_list
if isinstance(fragments_list, dict):
fragments_list = fragments_list.get("fragments", [])

# convert to list if it's just a dict
if not isinstance(fragments_list, list):
Expand Down Expand Up @@ -165,11 +166,13 @@ def acipolicygen_confcom(
fragment_imports.extend(policy.get_fragments())
for container in policy.get_images():
container_names.append(container.get_container_image())
# get all the fragments that are being used in the policy
fragment_policy_list = get_all_fragment_contents(container_names, fragment_imports)
for policy in container_group_policies:
policy.set_fragment_contents(fragment_policy_list)

for count, policy in enumerate(container_group_policies):
# this is where parameters and variables are populated
policy.populate_policy_content_for_all_images(
individual_image=bool(image_name), tar_mapping=tar_mapping, faster_hashing=faster_hashing
)
Expand Down
36 changes: 36 additions & 0 deletions src/confcom/azext_confcom/oras_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@
host_os = platform.system()
machine = platform.machine()

from knack.log import get_logger

logger = get_logger(__name__)


def prepend_docker_registry(image_name: str) -> str:
"""
Normalize a Docker image reference by adding `docker.io/library` if necessary.

Args:
image (str): The Docker image reference (e.g., `nginx:latest` or `myrepo/myimage`).

Returns:
str: The normalized Docker image reference.
"""
# Split the image into name and tag
if ":" in image_name:
name, _ = image_name.rsplit(":", 1)
else:
name, _ = image_name, "latest"

registry = ""
# Check if the image name contains a registry (e.g., docker.io, custom registry)
if "/" not in name or "." not in name.split("/")[0]:
# If no registry is specified, assume docker.io/library
if "/" not in name:
# Add the `library` namespace for official images
registry = f"library/"
# Add the default `docker.io` registry
registry = f"docker.io/" + registry

return f"{registry}{image_name}"

def call_oras_cli(args, check=False):
return subprocess.run(args, check=check, capture_output=True, timeout=120)
Expand All @@ -26,10 +58,14 @@ def call_oras_cli(args, check=False):
def discover(
image: str,
) -> List[str]:
# normalize the name in case the docker registry is implied
image = prepend_docker_registry(image)

arg_list = ["oras", "discover", image, "-o", "json", "--artifact-type", ARTIFACT_TYPE]
item = call_oras_cli(arg_list, check=False)
hashes = []

logger.info(f"Discovering fragments for {image}: {item.stdout.decode('utf-8')}")
if item.returncode == 0:
json_output = json.loads(item.stdout.decode("utf-8"))
manifests = json_output.get("manifests", [])
Expand Down
7 changes: 4 additions & 3 deletions src/confcom/azext_confcom/security_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def __init__(
container_image = UserContainerImage.from_json(c, is_vn2=is_vn2)
else:
container_image = ContainerImage.from_json(c)
container_image.parse_all_parameters_and_variables(self.all_params, self.all_vars)
container_results.append(container_image)

self._images = container_results
Expand Down Expand Up @@ -431,7 +432,6 @@ def populate_policy_content_for_all_images(
message_queue = []
# populate regular container images(s)
for image in container_images:
image.parse_all_parameters_and_variables(AciPolicy.all_params, AciPolicy.all_vars)
image_name = f"{image.base}:{image.tag}"

image_info, tar = get_image_info(progress, message_queue, tar_mapping, image)
Expand Down Expand Up @@ -517,6 +517,7 @@ def populate_policy_content_for_all_images(
}
image.set_user(user)

# should have all fragments before this point
if self._fragment_contents and self.should_eliminate_container_covered_by_fragments(image):
# these containers will get taken out later in the function
# since they are covered by a fragment
Expand Down Expand Up @@ -694,8 +695,8 @@ def load_policy_from_arm_template_str(
] = infrastructure_svn
if rego_imports:
# error check the rego imports for invalid data types
process_fragment_imports(rego_imports)
rego_fragments.extend(rego_imports)
processed_imports = process_fragment_imports(rego_imports)
rego_fragments.extend(processed_imports)

volumes = (
case_insensitive_dict_get(
Expand Down
4 changes: 4 additions & 0 deletions src/confcom/azext_confcom/template_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ def process_env_vars_from_config(container) -> List[Dict[str, str]]:

def process_fragment_imports(rego_imports) -> None:
for rego_import in rego_imports:
if not rego_import:
continue
feed = case_insensitive_dict_get(
rego_import, config.POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS_FEED
)
Expand Down Expand Up @@ -550,6 +552,8 @@ def process_fragment_imports(rego_imports) -> None:
+ "can only be a list value."
)

return rego_imports


def process_mounts(image_properties: dict, volumes: List[dict]) -> List[Dict[str, str]]:
mount_source_table_keys = config.MOUNT_SOURCE_TABLE.keys()
Expand Down