diff --git a/Makefile b/Makefile index ea3eeb654b..2456426991 100644 --- a/Makefile +++ b/Makefile @@ -77,8 +77,8 @@ generate-rosa-brand-logo: .PHONY: generate-hive-templates generate-hive-templates: generate-oauth-templates if [ -z ${IN_CONTAINER} ]; then \ - $(CONTAINER_ENGINE) run $(CONTAINER_RUN_FLAGS) registry.access.redhat.com/ubi8/python-39 /bin/bash -xc "cd `pwd -P`; pip install --disable-pip-version-check oyaml; curl -sSL https://github.com/open-cluster-management-io/policy-generator-plugin/releases/download/${POLICYGEN_VERSION}/linux-amd64-PolicyGenerator --output /opt/app-root/bin/PolicyGenerator; chmod +x /opt/app-root/bin/PolicyGenerator; ${GEN_POLICY_CONFIG}; ${GEN_POLICY_CONFIG_SP}; ${GEN_POLICY}; ${GEN_CMO_CONFIG}";\ - $(CONTAINER_ENGINE) run $(CONTAINER_RUN_FLAGS) registry.access.redhat.com/ubi8/python-39 /bin/bash -xc "cd `pwd -P`; pip install --disable-pip-version-check oyaml; ${GEN_TEMPLATE}"; \ + $(CONTAINER_ENGINE) run $(CONTAINER_RUN_FLAGS) registry.access.redhat.com/ubi9/python-312 /bin/bash -xc "cd `pwd -P`; pip install --disable-pip-version-check oyaml; curl -sSL https://github.com/open-cluster-management-io/policy-generator-plugin/releases/download/${POLICYGEN_VERSION}/linux-amd64-PolicyGenerator --output /opt/app-root/bin/PolicyGenerator; chmod +x /opt/app-root/bin/PolicyGenerator; ${GEN_POLICY_CONFIG}; ${GEN_POLICY_CONFIG_SP}; ${GEN_POLICY}; ${GEN_CMO_CONFIG}";\ + $(CONTAINER_ENGINE) run $(CONTAINER_RUN_FLAGS) registry.access.redhat.com/ubi9/python-312 /bin/bash -xc "cd `pwd -P`; pip install --disable-pip-version-check oyaml; ${GEN_TEMPLATE}"; \ else \ ${GEN_POLICY_CONFIG};\ ${GEN_POLICY_CONFIG_SP};\ diff --git a/scripts/generate_template.py b/scripts/generate_template.py index 193eb0c453..27b06b376a 100755 --- a/scripts/generate_template.py +++ b/scripts/generate_template.py @@ -7,9 +7,13 @@ import argparse import copy import re +from typing import Any cluster_platform_ann = "hive.openshift.io/cluster-platform" config_filename = "config.yaml" +environment_selector = "api.openshift.com/environment" +fedramp_selector = "api.openshift.com/fedramp" +valid_environments = ["production", "staging", "integration"] data_sss = [] data_resources = { @@ -96,6 +100,19 @@ def add_sss_for(name, directory, config): # collect the new sss for later processing data_sss.append(o) + +def expression_is_true(expression: dict[str, Any]) -> bool: + values = [v.lower() for v in expression["values"]] + match expression["operator"]: + case "In": + return "true" in values + case "NotIn": + return "false" in values + case "Eq": + return "true" in values + case _: + return False + if __name__ == '__main__': #Argument parser parser = argparse.ArgumentParser(description="template generation tool", usage='%(prog)s [options]') @@ -127,7 +144,7 @@ def add_sss_for(name, directory, config): deploymentMode = "SelectorSyncSet" if "deploymentMode" in config: - deploymentMode = config["deploymentMode"] + deploymentMode: str = config["deploymentMode"] # skip any directory only containing governance policies, as they are only for hypershift if deploymentMode == "Policy": @@ -159,6 +176,31 @@ def add_sss_for(name, directory, config): print("The selectorsyncset name should be lowercase. Found selectorsyncset with name " + sss_name) sys.exit(1) + # Verify that environment selectors make sense + sss = config["selectorSyncSet"] + valid_envs = valid_environments.copy() + expressions: list[dict[str, Any]] = sss.get("matchExpressions", []) if sss else [] + # FIXME: This is a workaround till https://issues.redhat.com/browse/HCMSEC-2597 is fixed. + # Until then 'stage' is a valid environment for fedramp + for expression in expressions: + if expression["key"] == fedramp_selector: + if expression_is_true(expression): + valid_envs.append('stage') + for expression in expressions: + if not expression["key"] == environment_selector: + continue + values: str|list[str] = expression["values"] + match values: + case list(x): + for value in x: + if value not in valid_envs: + raise RuntimeError(f"The environment value {value} for {dirpath} does not match a known environment: must be one of {valid_environments}") + case str(x): + if x not in valid_envs: + raise RuntimeError(f"The environment value {values} for {dirpath} does not match a known environment: must be one of {valid_environments}") + case _: + raise RuntimeError(f"Received invalid values {values} for {dirpath} for key: {environment_selector}") + # If no matchLabelsApplyMode, process as nornmal if "matchLabelsApplyMode" in config["selectorSyncSet"] and config["selectorSyncSet"]["matchLabelsApplyMode"] == "OR": # generate new SSS per matchLabels line