Skip to content

Commit

Permalink
Make port-forwards a property of vm block
Browse files Browse the repository at this point in the history
  • Loading branch information
fireflycons committed Aug 4, 2024
1 parent 6f138e0 commit 8b1a07c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 24 deletions.
28 changes: 17 additions & 11 deletions vagrant/generic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,27 @@ This is a generic template for building cross-platform Vagrant VM builds. It is
It should be very simple affair to customize this for a given project and more or less limited to

1. Define the network type by editing [NETWORK_SETTINGS](./Vagrantfile#L9).
* `NAT` - run VMs in a private network with the given [IP prefix](./Vagrantfile#L11) (the default is known to work with all 3 platforms) and [IP of the first machine](./Vagrantfile#L12) in the VM list. Subsequent machines will have contiguous IP addresses.
* `BRIDGE` - run VMs on host machine's LAN. Useful for Kubernetes deployments as it's not necessary to port-forward nodeports.
1. Define the VMs required by editing the [VIRTUAL_MACHINES](./Vagrantfile#L16) list and setting the properties for each machine in the list.
* All VMs will have `jq` and `yq` installed by default. Additional packages can be added by populating the [packages](./Vagrantfile#L22) list for each VM. Package names are specific to the VM's package manager (CentOS - `yum`, Ubuntu - `apt`).
1. Additional customizations such as port-forwards or shell provision steps can be added inside the [Hypervisor block](./Vagrantfile#L42-L45), using Hypervisor class's methods:

* `port_forward`
| Property | Required? | Value |
|-------------------|----------------|-------------------------------------------------------------------------------------------------------------|
| `network_type` | yes | `NAT` or `BRIDGE`. `BRIDGE` is useful for kube deployments as it's not necessary to port forward nodeports. |
| `private_network` | Only for `NAT` | Prefix of private network to run inside the hypervisor. The default is known to work with all 3 platforms. |
| `ip_start` | Only for `NAT` | IP of first VM on private network. Subsequent VMs will have contiguous IPs. |

Forward 8080 on host to 80 on guest

```ruby
hv.port_forward host: 8080, guest: 80
```
1. Define the VMs required by editing the [VIRTUAL_MACHINES](./Vagrantfile#L16) list and setting the properties for each machine in the list.


| Property | Required? | Value |
|------------|-----------|-----------------------------------------------------------------------------------------------------------------------------------------|
| `name` | yes | Name for the VM. Also sets the VM's hostname. |
| `cpu` | yes | Number of vCPU to add to guest. |
| `memory` | yes | Amount of RAM in MB. Total of all VMs must not exceed host system RAM minus 2GB, or an error will be raised. |
| `box` | yes | OS to install, either `Hypervisor.centos` or `Hypervisor.ubuntu` |
| `packages` | no | Optional list of extra packages to be installed via `yum` or `apt` as appropriate. All VMs will have `jq` and `yq` installed by default. |
| `ports` | no | Optional list of port forwards in the form `<host-port>:<guest-port>`. SSH (22) is automatically forwarded. Ignored for BRIDGE network. |

Note that the SSH port is automatically forwarded by Vagrant so you don't have to.
1. Additional customizations such as shell provision steps can be added inside the [Hypervisor block](./Vagrantfile#L45-L48), using Hypervisor class's methods:

* `provision_script`

Expand Down
7 changes: 5 additions & 2 deletions vagrant/generic/Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require_relative "./host"

# Define network that the virtual machines will join.
NETWORK_SETTINGS = {
network_type: "BRIDGE", # NAT = use a private network; BRIDGE = use addresses from your broadband router's network.
network_type: "NAT", # NAT = use a private network; BRIDGE = use addresses from your broadband router's network.
private_network: "192.168.56.", # Network prefix for VM network if using NAT mode. Ignored for BRIDGE.
ip_start: 11, # First IP to use for VMs on private network if using NAT mode. Ignored for BRIDGE.
}
Expand All @@ -19,7 +19,10 @@ VIRTUAL_MACHINES = [
cpu: 4, # Number of vCPUs to assign it
memory: 2048, # RAM in MB to assign it
box: Hypervisor.centos, # Operating system to run (centos or ubuntu)
#packages: ["some-package"], # Packages to be installed by OS's package manager
# packages: ["some-package"], # Packages to be installed by OS's package manager
ports: [ # Port forward rules (ignored when network is BRIDGE)
"8080:80", # host-port:guest-port
]
},
{
name: "target1",
Expand Down
36 changes: 25 additions & 11 deletions vagrant/generic/hypervisor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def needs_provision?
end
end


######################################################################################
#
# Hypervisor is an abstraction for the type of virtualization running on the host.
Expand Down Expand Up @@ -65,6 +64,21 @@ def deploy(vm:, network:, index:)
# If there are packages to install in guest, install them
self.provision_script vm[:packages].join(","), script: "package_install.sh"
end
if vm.key?(:ports)
if network[:network_type] == "NAT"
# If port fowards defined and networking is NAT
vm[:ports].each do |portspec|
p = portspec.split(":", -1)
if p.length < 2
puts "WARNING: Invalid port forward #{portspec}. Ignored."
else
self.port_forward host: p[0], guest: p[1]
end
end
else
puts "Port Forward rules ignored for BRIDGE network. They are unnecessary."
end
end
end

def network(network:, index:)
Expand All @@ -91,16 +105,6 @@ def network(network:, index:)
self.provision_script network[:private_network], network[:network_type], h.gateway_addresses, script: "setup_host.sh"
end

# Create an interface with given IP on hypervisor's private network
def private_network(ip:)
@@node.vm.network :private_network, ip: ip
end

# Port forward the given guest port to given port on host
def port_forward(guest:, host:)
@@node.vm.network "forwarded_port", guest: guest, host: host
end

# Run a shell script from distro specific directort
def provision_script(*args, script:)
s = ""
Expand All @@ -126,6 +130,7 @@ def self.centos()
dnf config-manager --set-enabled crb
dnf install -y epel-release epel-next-release
# Install YQ
echo "Installing yq..."
curl -sLo yq https://github.com/mikefarah/yq/releases/download/#{@yq_version}/yq_linux_arm64
chmod +x yq
mv yq /usr/bin/yq
Expand All @@ -134,6 +139,7 @@ def self.centos()
end
script = <<~EOF
# Install YQ
echo "Installing yq..."
curl -sLo yq https://github.com/mikefarah/yq/releases/download/#{@yq_version}/yq_linux_amd64
chmod +x yq
mv yq /usr/bin/yq
Expand All @@ -148,6 +154,7 @@ def self.ubuntu()
export DEBIAN_FRONTEND=noninteractive
apt update
apt-get install -y jq
echo "Installing yq..."
curl -sLo yq https://github.com/mikefarah/yq/releases/download/#{@yq_version}/yq_linux_#{arch}
chmod +x yq
mv yq /usr/bin/yq
Expand All @@ -165,6 +172,13 @@ def can_bridge?
def bridge_adapter
""
end

private

# Port forward the given guest port to given port on host
def port_forward(guest:, host:)
@@node.vm.network "forwarded_port", guest: guest, host: host
end
end

class VMware < Hypervisor
Expand Down

0 comments on commit 8b1a07c

Please sign in to comment.