diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d8bc4b4..79f8854 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,8 +24,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Git LFS Pull for deployment + - name: Update APT cache run: | + sudo apt-get update + + - name: Git LFS Pull for deployment + run: | echo "Pulling all Git LFS" git lfs pull -I **/challenges/**/ansible/**/* @@ -77,7 +81,6 @@ jobs: - name: Install dependencies run: | - sudo apt-get update sudo apt-get install --no-install-recommends --yes zfsutils-linux - name: Setup squid diff --git a/challenges/mock-track-apache-php/terraform/main.tf b/challenges/mock-track-apache-php/terraform/main.tf index 8de548d..14cacc1 100644 --- a/challenges/mock-track-apache-php/terraform/main.tf +++ b/challenges/mock-track-apache-php/terraform/main.tf @@ -96,7 +96,7 @@ resource "incus_instance" "this" { resource "incus_network_zone_record" "this" { for_each = local.instances - zone = "ctf" + zone = var.ctf_dns_network_zone name = each.value["record"] description = each.value["description"] diff --git a/challenges/mock-track-python-service/terraform/main.tf b/challenges/mock-track-python-service/terraform/main.tf index 7ba9a95..f03f938 100644 --- a/challenges/mock-track-python-service/terraform/main.tf +++ b/challenges/mock-track-python-service/terraform/main.tf @@ -96,7 +96,7 @@ resource "incus_instance" "this" { resource "incus_network_zone_record" "this" { for_each = local.instances - zone = "ctf" + zone = var.ctf_dns_network_zone name = each.value["record"] description = each.value["description"] diff --git a/ctf/templates/init/.deploy/common/dns.tf b/ctf/templates/init/.deploy/common/dns.tf index 6ae54c7..47524d7 100644 --- a/ctf/templates/init/.deploy/common/dns.tf +++ b/ctf/templates/init/.deploy/common/dns.tf @@ -4,3 +4,7 @@ resource "incus_network_zone" "this" { name = "ctf" description = "DNS zone for the internal .ctf TLD" } + +output "ctf_dns_network_zone" { + value = incus_network_zone.this.name +} \ No newline at end of file diff --git a/ctf/templates/init/.deploy/common/variables.tf b/ctf/templates/init/.deploy/common/variables.tf index fb674c4..c0ad782 100644 --- a/ctf/templates/init/.deploy/common/variables.tf +++ b/ctf/templates/init/.deploy/common/variables.tf @@ -13,6 +13,10 @@ variable "build_container" { type = bool } +variable "ctf_dns_network_zone" { + default = "ctf" + type = string +} locals { track = yamldecode(file("${path.module}/../track.yaml")) diff --git a/ctf/templates/new/common/main.tf.j2 b/ctf/templates/new/common/main.tf.j2 index 835c277..642131d 100644 --- a/ctf/templates/new/common/main.tf.j2 +++ b/ctf/templates/new/common/main.tf.j2 @@ -157,7 +157,7 @@ resource "incus_network_zone_record" "this" { # This resource is generated for each instances (the `locals` section of this file) for_each = local.instances - zone = "ctf" + zone = var.ctf_dns_network_zone name = each.value["record"] description = each.value["description"] diff --git a/ctf/utils.py b/ctf/utils.py index 8fd6bb5..678fe6e 100644 --- a/ctf/utils.py +++ b/ctf/utils.py @@ -106,7 +106,9 @@ def add_tracks_to_terraform_modules(tracks: set[Track]): build_container = {{ 'true' if track.require_build_container else 'false' }} {% if track.production %}deploy = "production"{% endif %} {% if track.remote %}incus_remote = "{{ track.remote }}"{% endif %} - depends_on = [module.common] + {% for ov in output_variables %} + {{ ov }} = module.common.{{ ov }} + {% endfor %} } {% endfor %} """ @@ -115,6 +117,7 @@ def add_tracks_to_terraform_modules(tracks: set[Track]): fd.write( template.render( tracks=tracks - get_terraform_tracks_from_modules(), + output_variables=get_common_modules_output_variables(), ) ) @@ -138,6 +141,84 @@ def create_terraform_modules_file(remote: str, production: bool = False): fd.write(template.render(production=production, remote=remote)) +def get_common_modules_output_variables() -> set[str]: + output_variables: set[str] = set() + output_variable_regex: re.Pattern = re.compile( + r'^output\s*"([a-zA-Z_\-]+)"\s*{', re.MULTILINE + ) + variable_regex: re.Pattern = re.compile( + r'^variable\s*"([a-zA-Z_\-]+)"\s*{', re.MULTILINE + ) + + variables: set[str] = set() + + for file in os.listdir( + path := os.path.join(find_ctf_root_directory(), ".deploy", "common") + ): + if file == "versions.tf": + continue + + with open(os.path.join(path, file), "r") as f: + match file: + case "variables.tf": + for i in variable_regex.findall(f.read()): + variables.add(i) + case _: + for i in output_variable_regex.findall(f.read()): + output_variables.add(i) + + for variable in output_variables - variables: + LOG.error( + msg + := f'Variable "{variable}" could not be found in "variables.tf". This could cause an issue when creating/destroying an environment.' + ) + + if ( + input(f'Do you want to add "{variable}" to "variables.tf"? [y/N] ').lower() + or "n" + ) == "n": + raise Exception(msg) + + try: + print("Do CTRL+C to cancel...") + while not (default := input("What is the default value? ")): + print("Do CTRL+C to cancel...") + + var_type = input("What is the type? [string] ") or "string" + + with open(os.path.join(path, "variables.tf"), "a") as f: + f.write("\n") + template = jinja2.Environment().from_string( + source=textwrap.dedent( + text="""\ + variable "{{variable}}" { + default = "{{default}}" + type = {{type}} + } + """ + ) + ) + f.write( + template.render(variable=variable, default=default, type=var_type) + ) + variables.add(variable) + except KeyboardInterrupt: + LOG.warning( + f'Cancelling the addition of the "{variable}" to "variables.tf".' + ) + + raise Exception(msg) + + if len(output_variables - variables) != 0: + LOG.critical( + msg + := f'Some output variables were not found in "variables.tf": {", ".join(output_variables - variables)}' + ) + raise Exception(msg) + + return output_variables & variables + + def get_terraform_tracks_from_modules() -> set[Track]: with open( file=os.path.join(find_ctf_root_directory(), ".deploy", "modules.tf"), mode="r" diff --git a/pyproject.toml b/pyproject.toml index 39c6334..27adece 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "typer==0.16.0", "pydantic" ] -version = "3.2.1" +version = "4.0.0" classifiers = [ "Programming Language :: Python :: 3", "Operating System :: OS Independent",