Skip to content

Commit

Permalink
added pipeline information
Browse files Browse the repository at this point in the history
  • Loading branch information
anacalva committed Mar 19, 2024
1 parent 85f0fe3 commit fbfacce
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 0 deletions.
111 changes: 111 additions & 0 deletions .github/workflows/vm-creation-terraform.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
name: Python
on:
push:
branches:
- main
- feature/*
- review/*
- fix/*

env:
pve_api_url: ${{ secrets.PVE_API_URL }}
pve_api_user: ${{ secrets.PVE_API_USER }}
pve_api_password: ${{ secrets.PVE_API_PASSWORD }}
vm_ssh_user: ${{ secrets.VM_SSH_USER }}
vm_ssh_password: ${{ secrets.VM_SSH_PASSWORD }}
pve_api_tls_verify: ${{ vars.PVE_API_TLS_VERIFY }}

jobs:

job_1:
runs-on: self-hosted

steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install github-action-utils PyYAML Jinja2
- name: Run Python to build main.tf from template
run: |
python3 tests/build_tf_file.py
- name: Upload main.tf file for job 2
uses: actions/upload-artifact@v4
with:
name: terraform_main
path: main.tf


job_2:

needs: job_1
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install github-action-utils python-terraform
- name: Download main.tf
uses: actions/download-artifact@v4
with:
name: terraform_main

- name: Run in Python Terraform Apply
run: |
python3 tests/terraform_apply.py
- name: Upload tfstate file for cleanup
if: always()
uses: actions/upload-artifact@v4
with:
name: terraform_state
path: terraform.tfstate

- name: Run in Python Terraform Destroy
run: |
python3 tests/terraform_destroy.py
cleanup:
if: ${{ always() }}
needs: job_2
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install github-action-utils python-terraform
- name: Download tfstate
uses: actions/download-artifact@v4
with:
name: terraform_state

- name: Download main
uses: actions/download-artifact@v4
with:
name: terraform_main

- name: Run Python Terraform Destroy
run: |
python3 tests/terraform_destroy.py
41 changes: 41 additions & 0 deletions tests/build_tf_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import yaml as yaml
import random
import string
from jinja2 import Environment, FileSystemLoader
import github_action_utils as gha_utils

def random_string_generation(length):
# choose random lowercase letters for unique name
letters = string.ascii_lowercase
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str

def write_file(testVars, output_file_name):
environment = Environment(loader=FileSystemLoader("tests/templates/"))
template = environment.get_template("module.tpl")
filename = "main.tf"
content = template.render(
name = output_file_name,
vm_count = random.choice(testVars['vm_count']),
vm_num_cpus = random.choice(testVars['vm_num_cpus']),
pve_datastore = random.choice(testVars['pve_datastore']),
)

# Save template
with open(filename, mode="w", encoding="utf-8") as message:
message.write(content)
print(f"... wrote {filename}")

def main():
### Generate Random String for VM name
str_tfvarName = "pipeline-" + random_string_generation(length = 5)
gha_utils.append_job_summary("Unique Name for VM's: " + str_tfvarName)

### Import Yaml file with all possible test values
with open('tests/test_values.yaml', 'r') as file:
testVars = yaml.safe_load(file)
print(testVars)
write_file(testVars, str_tfvarName)

if __name__ == '__main__':
main()
59 changes: 59 additions & 0 deletions tests/templates/module.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module "proxmox-vm" {
source = "git::https://github.com/stuttgart-things/proxmox-vm.git"
#source = "../../repos/proxmox-vm"
pve_api_url = var.pve_api_url
pve_api_user = var.pve_api_user
pve_api_password = var.pve_api_password
pve_api_tls_verify = var.pve_api_tls_verify
pve_cluster_node = "sthings-pve1"
pve_datastore = "{{ pve_datastore }}"
pve_folder_path = "stuttgart-things"
pve_network = "vmbr103"
vm_count = {{ vm_count }}
vm_name = "{{ name }}"
vm_notes = "vm-info"
vm_template = "ubuntu22"
vm_num_cpus = "{{ vm_num_cpus }}"
vm_memory = "4096"
vm_disk_size = "32G"
vm_ssh_user = var.vm_ssh_user
vm_ssh_password = var.vm_ssh_password
}

output "ip" {
value = module.proxmox-vm.ip
}

output "mac" {
value = module.proxmox-vm.mac
}

output "id" {
value = module.proxmox-vm.id
}


variable "pve_api_url" {
description = "url of proxmox api"
}

variable "pve_api_user" {
description = "username of proxmox api user"
}

variable "pve_api_password" {
description = "password of proxmox api user"
}

variable "vm_ssh_user" {
description = "username of proxmox api user"
}

variable "vm_ssh_password" {
description = "password of proxmox api user"
}

variable "pve_api_tls_verify" {
description = "proxmox API disable check if cert is valid"
}
53 changes: 53 additions & 0 deletions tests/terraform_apply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import python_terraform
import github_action_utils as gha_utils
import os

def main():
# Create tfvars variable with secrets
tfvars = {'pve_api_url': os.environ["pve_api_url"], "pve_api_user": os.environ["pve_api_user"], "pve_api_password": os.environ["pve_api_password"], "vm_ssh_user": os.environ["vm_ssh_user"], "vm_ssh_password": os.environ["vm_ssh_password"], "pve_api_tls_verify": os.environ["pve_api_tls_verify"]}

# Initialize the Terraform working directory
global tf
tf = python_terraform.Terraform(working_dir='.', variables=tfvars)
tf.init()

# Run terraform Apply and Terraform Destroy
list_ips=run_terraform()
ping_vms(list_ips)

def run_terraform():
# Plan the infrastructure changes
tf.plan(capture_output=False)

# Apply the infrastructure changes
tf.apply(skip_plan=True, capture_output=False)
str_output = tf.output()
gha_utils.append_job_summary("Results after apply:")
list_ips=str_output['ip']['value']

# Writes ip's of created vms in output.txt
f = open("output.txt", "a")
gha_utils.append_job_summary("Created VM's:")
for ip in list_ips:
gha_utils.append_job_summary("- " + ip)
f.write(f'{ip}\n')
f.close()

return list_ips

def ping_vms(list_ips):
list_responses = []
for ip in list_ips:
response = os.popen(f"ping -c 4 {ip} ").read()
print(response)
if ("Request timed out." and "unreachable") not in response:
list_responses = list_responses + [ip]

if not (list_ips == list_responses):
s = set(list_responses)
list_nonActive = [x for x in list_ips if x not in s]
gha_utils.error("The following vm's are non-responsive: " + str(list_nonActive), title="Error Title")
assert False

if __name__ == '__main__':
main()
23 changes: 23 additions & 0 deletions tests/terraform_destroy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import python_terraform
import github_action_utils as gha_utils
import os

def main():
tfvars = {'pve_api_url': os.environ["pve_api_url"], "pve_api_user": os.environ["pve_api_user"], "pve_api_password": os.environ["pve_api_password"], "vm_ssh_user": os.environ["vm_ssh_user"], "vm_ssh_password": os.environ["vm_ssh_password"], "pve_api_tls_verify": os.environ["pve_api_tls_verify"]}

# Initialize the Terraform working directory
global tf
tf = python_terraform.Terraform(working_dir='.', variables=tfvars)
tf.init()

run_terraform()

def run_terraform():
# Destroys created vms
results = tf.destroy(force=None, auto_approve=True)
print("Destroy Results:")
print(results[1])
gha_utils.append_job_summary("Results after destroy: " + str(results[1]).splitlines()[-1])

if __name__ == '__main__':
main()
14 changes: 14 additions & 0 deletions tests/test_values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
# names should be match what the module expects
vm_count: # list or thing of range notation like 1-3; # should pick one of them randomly
- 1
- 2
- 3
vm_num_cpus: # should pick one of them randomly
- 2
- 4
- 8
#vm_name: #E.G. RANDOM NAME W/ LENGHT XY OR PREFIX MAYBE - UP TO YOU BUT THING OF CONSTRAINS LIKE LENGHT OR FORBIDDEN CHARS LIKE _
pve_datastore: # should pick one of them randomly
- datastore
- v3700

0 comments on commit fbfacce

Please sign in to comment.