diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc index c3357752..6f825127 100644 Binary files a/app/__pycache__/__init__.cpython-311.pyc and b/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/app/__pycache__/models.cpython-311.pyc b/app/__pycache__/models.cpython-311.pyc deleted file mode 100644 index b3bdf8fa..00000000 Binary files a/app/__pycache__/models.cpython-311.pyc and /dev/null differ diff --git a/app/__pycache__/prompt_generators.cpython-311.pyc b/app/__pycache__/prompt_generators.cpython-311.pyc index bcbcb9df..c8c4085e 100644 Binary files a/app/__pycache__/prompt_generators.cpython-311.pyc and b/app/__pycache__/prompt_generators.cpython-311.pyc differ diff --git a/app/__pycache__/test_services.cpython-311-pytest-7.4.0.pyc b/app/__pycache__/test_services.cpython-311-pytest-7.4.0.pyc deleted file mode 100644 index 9ec3e953..00000000 Binary files a/app/__pycache__/test_services.cpython-311-pytest-7.4.0.pyc and /dev/null differ diff --git a/app/__pycache__/test_services.cpython-311-pytest-8.3.3.pyc b/app/__pycache__/test_services.cpython-311-pytest-8.3.3.pyc deleted file mode 100644 index 9ec3e953..00000000 Binary files a/app/__pycache__/test_services.cpython-311-pytest-8.3.3.pyc and /dev/null differ diff --git a/app/directory_generators/terraform_generator.py b/app/directory_generators/terraform_generator.py index ae23fedb..1bc1ba99 100644 --- a/app/directory_generators/terraform_generator.py +++ b/app/directory_generators/terraform_generator.py @@ -1,88 +1,143 @@ import os - project_name = "app/media/MyTerraform" -base_directory = project_name.replace("/", os.sep) -modules_directory = os.path.join(base_directory, "modules") -ci_directory = os.path.join(base_directory, ".github", "workflows") - -os.makedirs(modules_directory, exist_ok=True) -os.makedirs(ci_directory, exist_ok=True) - -terraform_main = f"""provider "aws" {{ - region = "us-east-1" -}} - -resource "aws_instance" "web" {{ - ami = "ami-0c55b159cbfafe1f0" - instance_type = "t2.micro" - - tags = {{ - Name = "MyEC2Instance" - }} -}} -""" - -terraform_variables = """variable "region" {{ - description = "AWS region" +modules_dir = os.path.join(project_name, "modules") +docker_dir = os.path.join(modules_dir, "docker") + +# Create project directories +os.makedirs(docker_dir, exist_ok=True) + +# Create main.tf at root +with open(os.path.join(project_name, "main.tf"), "w") as main_file: + main_file.write('''provider "docker" { + host = var.docker_host +} + +module "docker" { + source = "./modules/docker" + image = var.image + name = var.container_name + ports = var.ports +} +''') + +# Create variables.tf at root +with open(os.path.join(project_name, "variables.tf"), "w") as variables_file: + variables_file.write('''variable "docker_host" { + description = "The Docker host Uri." + type = string +} + +variable "image" { + description = "The Docker image to use." type = string - default = "us-east-1" -}} +} -variable "instance_type" {{ - description = "EC2 Instance type" +variable "container_name" { + description = "The name of the Docker container." + type = string +} + +variable "ports" { + description = "List of ports to expose." + type = list(string) +} +''') + +# Create terraform.tfvars at root +with open(os.path.join(project_name, "terraform.tfvars"), "w") as tfvars_file: + tfvars_file.write('''docker_host = "tcp://localhost:2375" +image = "nginx:latest" +container_name = "my_nginx" +ports = ["80:80"] +''') + +# Create versions.tf at root +with open(os.path.join(project_name, "versions.tf"), "w") as versions_file: + versions_file.write('''terraform { + required_version = ">= 1.0" + + required_providers { + docker = { + source = "hashicorp/docker" + version = ">= 2.0" + } + } +} +''') + +# Create outputs.tf at root +with open(os.path.join(project_name, "outputs.tf"), "w") as outputs_file: + outputs_file.write('''output "container_id" { + description = "The ID of the Docker container." + value = module.docker.container_id +} + +output "container_ip" { + description = "The IP address of the Docker container." + value = module.docker.container_ip +} +''') + +# Create main.tf in modules/docker +with open(os.path.join(docker_dir, "main.tf"), "w") as docker_main_file: + docker_main_file.write('''resource "docker_container" "this" { + name = var.name + image = var.image + ports { + internal = var.ports[0] + external = var.ports[1] + } +} +''') + +# Create variables.tf in modules/docker +with open(os.path.join(docker_dir, "variables.tf"), "w") as docker_variables_file: + docker_variables_file.write('''variable "image" { + description = "The Docker image to use." type = string - default = "t2.micro" -}} +} -variable "ami" {{ - description = "AMI ID" +variable "name" { + description = "The name of the Docker container." type = string - default = "ami-0c55b159cbfafe1f0" -}} -""" - -github_actions = """name: Terraform CI - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - terraform: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 - with: - terraform_version: 1.0.0 - - - name: Terraform Init - run: terraform init - - - name: Terraform Plan - run: terraform plan - - - name: Terraform Apply - run: terraform apply -auto-approve - env: - TF_VAR_region: ${{ secrets.AWS_REGION }} - TF_VAR_instance_type: ${{ secrets.AWS_INSTANCE_TYPE }} - TF_VAR_ami: ${{ secrets.AWS_AMI }} -""" - -with open(os.path.join(base_directory, "main.tf"), "w") as f: - f.write(terraform_main) - -with open(os.path.join(base_directory, "variables.tf"), "w") as f: - f.write(terraform_variables) - -with open(os.path.join(ci_directory, "terraform-ci.yml"), "w") as f: - f.write(github_actions) \ No newline at end of file +} + +variable "ports" { + description = "List of ports for the container." + type = list(string) +} +''') + +# Create terraform.tfvars in modules/docker +with open(os.path.join(docker_dir, "terraform.tfvars"), "w") as docker_tfvars_file: + docker_tfvars_file.write('''image = "nginx:latest" +name = "my_nginx" +ports = ["80", "80"] +''') + +# Create versions.tf in modules/docker +with open(os.path.join(docker_dir, "versions.tf"), "w") as docker_versions_file: + docker_versions_file.write('''terraform { + required_version = ">= 1.0" + + required_providers { + docker = { + source = "hashicorp/docker" + version = ">= 2.0" + } + } +} +''') + +# Create outputs.tf in modules/docker +with open(os.path.join(docker_dir, "outputs.tf"), "w") as docker_outputs_file: + docker_outputs_file.write('''output "container_id" { + description = "The ID of the Docker container." + value = docker_container.this.id +} + +output "container_ip" { + description = "The IP address of the Docker container." + value = docker_container.this.ip_address +} +''') \ No newline at end of file diff --git a/app/media/MyTerraform/.github/workflows/terraform-ci.yml b/app/media/MyTerraform/.github/workflows/terraform-ci.yml deleted file mode 100644 index 8c6e977e..00000000 --- a/app/media/MyTerraform/.github/workflows/terraform-ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Terraform CI - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - terraform: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 - with: - terraform_version: 1.0.0 - - - name: Terraform Init - run: terraform init - - - name: Terraform Plan - run: terraform plan - - - name: Terraform Apply - run: terraform apply -auto-approve - env: - TF_VAR_region: ${{ secrets.AWS_REGION }} - TF_VAR_instance_type: ${{ secrets.AWS_INSTANCE_TYPE }} - TF_VAR_ami: ${{ secrets.AWS_AMI }} diff --git a/app/media/MyTerraform/main.tf b/app/media/MyTerraform/main.tf index 71842c53..24dc98d6 100644 --- a/app/media/MyTerraform/main.tf +++ b/app/media/MyTerraform/main.tf @@ -1,12 +1,10 @@ -provider "aws" { - region = "us-east-1" +provider "docker" { + host = var.docker_host } -resource "aws_instance" "web" { - ami = "ami-0c55b159cbfafe1f0" - instance_type = "t2.micro" - - tags = { - Name = "MyEC2Instance" - } +module "docker" { + source = "./modules/docker" + image = var.image + name = var.container_name + ports = var.ports } diff --git a/app/media/MyTerraform/modules/docker/main.tf b/app/media/MyTerraform/modules/docker/main.tf new file mode 100644 index 00000000..39698800 --- /dev/null +++ b/app/media/MyTerraform/modules/docker/main.tf @@ -0,0 +1,8 @@ +resource "docker_container" "this" { + name = var.name + image = var.image + ports { + internal = var.ports[0] + external = var.ports[1] + } +} diff --git a/app/media/MyTerraform/modules/docker/outputs.tf b/app/media/MyTerraform/modules/docker/outputs.tf new file mode 100644 index 00000000..7e2f1ae9 --- /dev/null +++ b/app/media/MyTerraform/modules/docker/outputs.tf @@ -0,0 +1,9 @@ +output "container_id" { + description = "The ID of the Docker container." + value = docker_container.this.id +} + +output "container_ip" { + description = "The IP address of the Docker container." + value = docker_container.this.ip_address +} diff --git a/app/media/MyTerraform/modules/docker/terraform.tfvars b/app/media/MyTerraform/modules/docker/terraform.tfvars new file mode 100644 index 00000000..da3445f5 --- /dev/null +++ b/app/media/MyTerraform/modules/docker/terraform.tfvars @@ -0,0 +1,3 @@ +image = "nginx:latest" +name = "my_nginx" +ports = ["80", "80"] diff --git a/app/media/MyTerraform/modules/docker/variables.tf b/app/media/MyTerraform/modules/docker/variables.tf new file mode 100644 index 00000000..91697644 --- /dev/null +++ b/app/media/MyTerraform/modules/docker/variables.tf @@ -0,0 +1,14 @@ +variable "image" { + description = "The Docker image to use." + type = string +} + +variable "name" { + description = "The name of the Docker container." + type = string +} + +variable "ports" { + description = "List of ports for the container." + type = list(string) +} diff --git a/app/media/MyTerraform/modules/docker/versions.tf b/app/media/MyTerraform/modules/docker/versions.tf new file mode 100644 index 00000000..3b14c52c --- /dev/null +++ b/app/media/MyTerraform/modules/docker/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + docker = { + source = "hashicorp/docker" + version = ">= 2.0" + } + } +} diff --git a/app/media/MyTerraform/outputs.tf b/app/media/MyTerraform/outputs.tf new file mode 100644 index 00000000..c5196f76 --- /dev/null +++ b/app/media/MyTerraform/outputs.tf @@ -0,0 +1,9 @@ +output "container_id" { + description = "The ID of the Docker container." + value = module.docker.container_id +} + +output "container_ip" { + description = "The IP address of the Docker container." + value = module.docker.container_ip +} diff --git a/app/media/MyTerraform/terraform.tfvars b/app/media/MyTerraform/terraform.tfvars new file mode 100644 index 00000000..e42cd5ea --- /dev/null +++ b/app/media/MyTerraform/terraform.tfvars @@ -0,0 +1,4 @@ +docker_host = "tcp://localhost:2375" +image = "nginx:latest" +container_name = "my_nginx" +ports = ["80:80"] diff --git a/app/media/MyTerraform/variables.tf b/app/media/MyTerraform/variables.tf index e3b293c4..edfed105 100644 --- a/app/media/MyTerraform/variables.tf +++ b/app/media/MyTerraform/variables.tf @@ -1,17 +1,19 @@ -variable "region" {{ - description = "AWS region" +variable "docker_host" { + description = "The Docker host Uri." type = string - default = "us-east-1" -}} +} -variable "instance_type" {{ - description = "EC2 Instance type" +variable "image" { + description = "The Docker image to use." type = string - default = "t2.micro" -}} +} -variable "ami" {{ - description = "AMI ID" +variable "container_name" { + description = "The name of the Docker container." type = string - default = "ami-0c55b159cbfafe1f0" -}} +} + +variable "ports" { + description = "List of ports to expose." + type = list(string) +} diff --git a/app/media/MyTerraform/versions.tf b/app/media/MyTerraform/versions.tf new file mode 100644 index 00000000..3b14c52c --- /dev/null +++ b/app/media/MyTerraform/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + docker = { + source = "hashicorp/docker" + version = ">= 2.0" + } + } +} diff --git a/app/models/__pycache__/terraform_models.cpython-311.pyc b/app/models/__pycache__/terraform_models.cpython-311.pyc index c8e0289c..b7df6d2b 100644 Binary files a/app/models/__pycache__/terraform_models.cpython-311.pyc and b/app/models/__pycache__/terraform_models.cpython-311.pyc differ diff --git a/app/models/terraform_models.py b/app/models/terraform_models.py index 2b21c691..33459ac2 100644 --- a/app/models/terraform_models.py +++ b/app/models/terraform_models.py @@ -70,7 +70,7 @@ class IaCTemplateGeneration(BaseModel): @validator("base_config") def validate_base_config(cls, value): - allowed_configs = ['ec2', 's3', 'rds'] + allowed_configs = ['ec2', 's3', 'rds','docker'] if value not in allowed_configs: raise ValueError(f"Base config must be one of {allowed_configs}.") return value diff --git a/app/prompt_generators.py b/app/prompt_generators.py index c6f14225..7366cf82 100644 --- a/app/prompt_generators.py +++ b/app/prompt_generators.py @@ -68,6 +68,10 @@ def IaC_template_generator(input : IaCTemplateGeneration) -> str: sensitive values. - versions.tf: - Contains the `terraform` and `provider` blocks, specifying required versions. + + - If {input.base_config} is a Docker resource, set kreuzwerker/docker as the provider with appropriate version constraints. + - If {input.base_config} is an AWS resource, set hashicorp/aws as the provider with suitable version constraints. + - Structure the `terraform` block as: terraform {{ required_version = ">= 1.0" @@ -103,6 +107,9 @@ def IaC_template_generator(input : IaCTemplateGeneration) -> str: typical configuration values, making it easier to set up and reducing the need for hardcoded values. - versions.tf: - Contains the `terraform` and `provider` blocks, specifying required versions. + - If {input.base_config} is a Docker resource, set kreuzwerker/docker as the provider with appropriate version constraints. + - If {input.base_config} is an AWS resource, set hashicorp/aws as the provider with suitable version constraints. + - Structure the `terraform` block as: terraform {{ required_version = ">= 1.0" diff --git a/app/tests/__pycache__/__init__.cpython-311.pyc b/app/tests/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..f2c2c433 Binary files /dev/null and b/app/tests/__pycache__/__init__.cpython-311.pyc differ diff --git a/app/tests/__pycache__/test_helm_template.cpython-311-pytest-8.3.3.pyc b/app/tests/__pycache__/test_helm_template.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 00000000..a8889bfc Binary files /dev/null and b/app/tests/__pycache__/test_helm_template.cpython-311-pytest-8.3.3.pyc differ diff --git a/app/tests/__pycache__/test_iac_basic.cpython-311-pytest-8.3.3.pyc b/app/tests/__pycache__/test_iac_basic.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 00000000..0a420fea Binary files /dev/null and b/app/tests/__pycache__/test_iac_basic.cpython-311-pytest-8.3.3.pyc differ diff --git a/app/tests/__pycache__/test_iac_bugfix.cpython-311-pytest-8.3.3.pyc b/app/tests/__pycache__/test_iac_bugfix.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 00000000..3d488caa Binary files /dev/null and b/app/tests/__pycache__/test_iac_bugfix.cpython-311-pytest-8.3.3.pyc differ diff --git a/app/tests/__pycache__/test_iac_install.cpython-311-pytest-8.3.3.pyc b/app/tests/__pycache__/test_iac_install.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 00000000..11a251a6 Binary files /dev/null and b/app/tests/__pycache__/test_iac_install.cpython-311-pytest-8.3.3.pyc differ diff --git a/app/tests/__pycache__/test_iac_template.cpython-311-pytest-8.3.3.pyc b/app/tests/__pycache__/test_iac_template.cpython-311-pytest-8.3.3.pyc new file mode 100644 index 00000000..417834f9 Binary files /dev/null and b/app/tests/__pycache__/test_iac_template.cpython-311-pytest-8.3.3.pyc differ diff --git a/app/tests/test_iac_template.py b/app/tests/test_iac_template.py index 1a2d5a3e..facd4ee0 100644 --- a/app/tests/test_iac_template.py +++ b/app/tests/test_iac_template.py @@ -46,7 +46,7 @@ def test_template_invalid(mock_execute_pythonfile, mock_edit_directory_generator assert "detail" in response.json(), "Response JSON does not contain 'detail'" errors = response.json()["detail"] expected_error_loc = ["body", "base_config"] - expected_error_msg = "Base config must be one of ['ec2', 's3', 'rds']." + expected_error_msg = "Value error, Base config must be one of ['ec2', 's3', 'rds', 'docker']." assert any( error["loc"] == expected_error_loc and expected_error_msg in error["msg"] for error in errors