From 6eabd400218cbeef6bc4c76e67a10f2beebe1826 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 4 Aug 2025 21:44:28 +0100 Subject: [PATCH] added vagrant build --- .gitignore | 3 + ansible/install_keepalived.yaml | 79 ++++++++++++++++++++++++++ ansible/requirements.txt | 36 ++++++++++++ pipelines/dev/vagrant-k3s.json | 11 ++++ scripts/ansible_inventory.ini | 9 +++ scripts/configure_vagrant.sh | 0 scripts/configure_vagrant_k3s.sh | 95 +++++++++++++++++++++++++++++++- vagrant/dev/ubuntu/Vagrantfile | 19 ++++--- 8 files changed, 240 insertions(+), 12 deletions(-) create mode 100644 ansible/install_keepalived.yaml create mode 100644 ansible/requirements.txt create mode 100644 pipelines/dev/vagrant-k3s.json create mode 100644 scripts/ansible_inventory.ini create mode 100644 scripts/configure_vagrant.sh diff --git a/.gitignore b/.gitignore index 7a7de18..38886ff 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ scripts/galene/data/ .vscode bin deleted +*/venv* + +.vagrant diff --git a/ansible/install_keepalived.yaml b/ansible/install_keepalived.yaml new file mode 100644 index 0000000..1dcc596 --- /dev/null +++ b/ansible/install_keepalived.yaml @@ -0,0 +1,79 @@ +--- +- name: Install keepalived on 3-node cluster + hosts: vm1,vm2,vm3 + become: true + become_user: root + serial: 1 # Ensure tasks are executed one host at a time + + vars_files: + - vault.yml + - vars.yml + + vars: + tailscale_host: "{{ hostvars[inventory_hostname]['tailscale_host'] }}" + + tasks: + # - name: Debug gathered facts + # ansible.builtin.debug: + # var: ansible_facts + + # - name: List all network interfaces and their IPs + # ansible.builtin.debug: + # msg: "{{ item.key }}: {{ item.value.ipv4 | map(attribute='address') | list }}" + # with_dict: "{{ ansible_facts['network_interfaces'] }}" + # when: ansible_facts['network_interfaces'] is defined + + - name: Detect interface with the desired IP range + ansible.builtin.set_fact: + keepalived_interface: "{{ item.key }}" + with_dict: "{{ ansible_facts['network_interfaces'] }}" + when: item.value.ipv4 is defined and item.value.ipv4 | selectattr('address', 'search', '^192\\.168\\.56\\.') | list | length > 0 + register: detected_interface + + - name: Set detected interface fact + ansible.builtin.set_fact: + keepalived_interface: "{{ detected_interface.ansible_facts.keepalived_interface }}" + when: detected_interface is defined and detected_interface.ansible_facts is defined + + - name: Fallback to default interface if no match is found + ansible.builtin.set_fact: + keepalived_interface: "enp0s8" + when: keepalived_interface is not defined + + - name: Fail if no interface is detected even after fallback + ansible.builtin.fail: + msg: "No interface with the desired IP range was detected, and fallback to default interface failed." + when: keepalived_interface is not defined + + - name: Install keepalived + ansible.builtin.apt: + name: keepalived + state: present + + - name: Configure keepalived on each node with decremented priority + ansible.builtin.copy: + dest: /etc/keepalived/keepalived.conf + content: | + vrrp_instance VI_1 { + state MASTER + interface {{ keepalived_interface }} + virtual_router_id 51 + priority {{ 100 - (groups['vms'].index(inventory_hostname)) }} + advert_int 1 + authentication { + auth_type PASS + auth_pass mysecret + } + virtual_ipaddress { + 192.168.56.250 + } + } + owner: root + group: root + mode: "0644" + + - name: Enable and restart keepalived service + ansible.builtin.systemd: + name: keepalived + enabled: true + state: restarted diff --git a/ansible/requirements.txt b/ansible/requirements.txt new file mode 100644 index 0000000..e27b225 --- /dev/null +++ b/ansible/requirements.txt @@ -0,0 +1,36 @@ +ansible==10.2.0 +ansible-compat==24.10.0 +ansible-core==2.17.2 +ansible-lint==24.12.2 +attrs==24.3.0 +black==24.10.0 +bracex==2.5.post1 +certifi==2024.7.4 +cffi==1.16.0 +charset-normalizer==3.3.2 +click==8.1.8 +cryptography==43.0.0 +filelock==3.16.1 +idna==3.7 +importlib_metadata==8.5.0 +Jinja2==3.1.4 +jsonschema==4.23.0 +jsonschema-specifications==2024.10.1 +MarkupSafe==2.1.5 +mypy-extensions==1.0.0 +packaging==24.1 +pathspec==0.12.1 +platformdirs==4.3.6 +pycparser==2.22 +PyYAML==6.0.1 +referencing==0.35.1 +requests==2.32.3 +resolvelib==1.0.1 +rpds-py==0.22.3 +ruamel.yaml==0.18.10 +ruamel.yaml.clib==0.2.12 +subprocess-tee==0.4.2 +urllib3==2.2.2 +wcmatch==10.0 +yamllint==1.35.1 +zipp==3.21.0 diff --git a/pipelines/dev/vagrant-k3s.json b/pipelines/dev/vagrant-k3s.json new file mode 100644 index 0000000..fdf476b --- /dev/null +++ b/pipelines/dev/vagrant-k3s.json @@ -0,0 +1,11 @@ +[ + { + "name": "pre-requisties", + "function": "RunCommand", + "params": [ + "./scripts/vagrant_check_prerequisites.sh" + ], + "retryCount": 0, + "shouldAbort": true + } +] diff --git a/scripts/ansible_inventory.ini b/scripts/ansible_inventory.ini new file mode 100644 index 0000000..9d984c7 --- /dev/null +++ b/scripts/ansible_inventory.ini @@ -0,0 +1,9 @@ +[all] +vm1 ansible_host=127.0.0.1 ansible_port=2222 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm1/virtualbox/private_key ansible_python_interpreter=/usr/bin/python3 +vm2 ansible_host=127.0.0.1 ansible_port=2200 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm2/virtualbox/private_key ansible_python_interpreter=/usr/bin/python3 +vm3 ansible_host=127.0.0.1 ansible_port=2201 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm3/virtualbox/private_key ansible_python_interpreter=/usr/bin/python3 + +[vms] +vm1 +vm2 +vm3 diff --git a/scripts/configure_vagrant.sh b/scripts/configure_vagrant.sh new file mode 100644 index 0000000..e69de29 diff --git a/scripts/configure_vagrant_k3s.sh b/scripts/configure_vagrant_k3s.sh index 48ae939..3e04038 100755 --- a/scripts/configure_vagrant_k3s.sh +++ b/scripts/configure_vagrant_k3s.sh @@ -20,6 +20,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "Script directory: $SCRIPT_DIR" VAGRANT_DIR="$SCRIPT_DIR/../vagrant/dev/ubuntu/" +echo "Vagrant directory: $VAGRANT_DIR" cd "$VAGRANT_DIR" || { echo "Failed to change directory to Vagrant directory: $VAGRANT_DIR" @@ -33,6 +34,7 @@ if [ -z "$(vagrant status | grep 'running')" ]; then fi network_info=() +vagrant_ports=() echo "Gathering network information from running VMs..." running_vms=$(vagrant status | grep "running" | awk '{print $1}') @@ -41,9 +43,8 @@ for vm in $running_vms; do # Check network interfaces vm_info=$(vagrant ssh "$vm" -c "ip -j addr" | jq -r ' - .[] | - "Interface: \(.ifname)\n" + vm_info=$(vagrant ssh "$vm" -c "ip -j addr" | jq -r ' - + .[] | + "Interface: \(.ifname)\n" + (if .addr_info then (.addr_info | map(" IP (\(.family)): \(.local)") | join("\n")) else @@ -66,6 +67,34 @@ done echo "Network information gathered successfully." + +# get vagrant ports +echo "Gathering Vagrant port information..." +# vagrant ssh-config | grep Port | while read -r line; do +# echo "Processing line: $line" + +# # Processing line: Port 2222 +# # Processing line: Port 2200 +# # Processing line: Port 2201 + + +# port=$(echo "$line" | awk '{print $2}') +# echo "Extracted port: $port" +# vagrant_ports+=("$port") +# done + + +while read -r line; do + echo "Processing line: $line" + + # Extract the port number + port=$(echo "$line" | awk '{print $2}') + echo "Extracted port: $port" + vagrant_ports+=("$port") +done < <(vagrant ssh-config | grep Port) + + + # Print network information for info in "${network_info[@]}"; do echo "----------------------------------------" @@ -73,5 +102,65 @@ for info in "${network_info[@]}"; do echo "----------------------------------------" done +# Print Vagrant ports +echo "Vagrant Ports:" +for port in "${vagrant_ports[@]}"; do + echo "Port: $port" +done +# create an ansible inventory file +# [all] +# vm1 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm1/virtualbox/private_key +# vm2 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm2/virtualbox/private_key +# vm3 ansible_host= ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/vm3/virtualbox/private_key + +# echo "Creating Ansible inventory file..." +# inventory_file="$SCRIPT_DIR/ansible_inventory.ini" +# echo "[all]" > "$inventory_file" +# i=0 +# for vm in $running_vms; do +# port="${vagrant_ports[$i]}" +# echo "$vm ansible_host=127.0.0.1 ansible_port=$port ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/$vm/virtualbox/private_key" >> "$inventory_file" +# ((i++)) +# done +echo "Creating Ansible inventory file..." +inventory_file="$SCRIPT_DIR/ansible_inventory.ini" +echo "[all]" > "$inventory_file" +i=0 +for vm in $running_vms; do + port="${vagrant_ports[$i]}" + echo "$vm ansible_host=127.0.0.1 ansible_port=$port ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/$vm/virtualbox/private_key ansible_python_interpreter=/usr/bin/python3" >> "$inventory_file" + ((i++)) +done + +echo "" >> "$inventory_file" +# echo "[children]" >> "$inventory_file" +# echo "vm_group" >> "$inventory_file" +# echo "" >> "$inventory_file" +echo "[vms]" >> "$inventory_file" +for vm in $running_vms; do + echo $vm >> "$inventory_file" +done + +echo "Ansible inventory file created at: $inventory_file" + +# source venv ansible +ANSIBLE_VENV_DIR="$SCRIPT_DIR/../ansible/venv" +if [ -d "$ANSIBLE_VENV_DIR" ]; then + echo "Activating Ansible virtual environment..." + source "$ANSIBLE_VENV_DIR/bin/activate" +else + echo "Ansible virtual environment not found at $ANSIBLE_VENV_DIR. Please create it before running this script." + exit 1 +fi + +ANSIBLE_HOST_KEY_CHECKING=False ansible --inventory-file ../../../scripts/ansible_inventory.ini -m ping all | cat + +# exit if error from ping +if [ $? -ne 0 ]; then + echo "Ansible ping failed. Please check your Vagrant VMs and network configuration." + exit 1 +fi + +ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook ../../../ansible/install_keepalived.yaml --inventory-file ../../../scripts/ansible_inventory.ini | cat diff --git a/vagrant/dev/ubuntu/Vagrantfile b/vagrant/dev/ubuntu/Vagrantfile index 49a2f30..6e33efc 100644 --- a/vagrant/dev/ubuntu/Vagrantfile +++ b/vagrant/dev/ubuntu/Vagrantfile @@ -8,7 +8,7 @@ Vagrant.configure("2") do |config| # VM 1 Configuration config.vm.define "vm1" do |vm1| - vm1.vm.box = "hashicorp/bionic64" + vm1.vm.box = "ubuntu/jammy64" # run ip link to list network interfaces on linux # run ipconfig to list network interfaces on Windows @@ -33,7 +33,7 @@ Vagrant.configure("2") do |config| # Uncomment the following line to use a specific network interface for the public network # and replace "wlp0s20f3" with your actual network interface name. - # vm1.vm.network "public_network", bridge: "wlp0s20f3" + vm1.vm.network "public_network", bridge: "wlp0s20f3" vm1.vm.network "private_network", type: "dhcp" @@ -44,13 +44,14 @@ Vagrant.configure("2") do |config| vm1.vm.provision "shell", inline: <<-SHELL sudo apt-get update - sudo apt-get install -y jq + sudo apt-get install -y software-properties-common python3-pip python3-apt jq + # python3 -m pip install --upgrade pip SHELL end # VM 2 Configuration config.vm.define "vm2" do |vm2| - vm2.vm.box = "hashicorp/bionic64" + vm2.vm.box = "ubuntu/jammy64" # Private network for inter-VM communication using DHCP vm2.vm.network "private_network", type: "dhcp" @@ -65,13 +66,14 @@ Vagrant.configure("2") do |config| vm2.vm.provision "shell", inline: <<-SHELL sudo apt-get update - sudo apt-get install -y jq + sudo apt-get install -y software-properties-common python3-pip python3-apt jq + # python3 -m pip install --upgrade pip SHELL end # VM 3 Configuration config.vm.define "vm3" do |vm3| - vm3.vm.box = "hashicorp/bionic64" + vm3.vm.box = "ubuntu/jammy64" # Private network for inter-VM communication using DHCP vm3.vm.network "private_network", type: "dhcp" @@ -86,9 +88,8 @@ Vagrant.configure("2") do |config| vm3.vm.provision "shell", inline: <<-SHELL sudo apt-get update - sudo apt-get install -y jq + sudo apt-get install -y software-properties-common python3-pip python3-apt jq + # python3 -m pip install --upgrade pip SHELL - - end end