Skip to content

Instantly share code, notes, and snippets.

@noslin005
Created December 3, 2024 02:40
Show Gist options
  • Save noslin005/e33a514a82b0bfadb14994924473c8c4 to your computer and use it in GitHub Desktop.
Save noslin005/e33a514a82b0bfadb14994924473c8c4 to your computer and use it in GitHub Desktop.
slack-vm1:
default_gateway: 192.168.1.1
interfaces:
- name: eth0
addresses:
- 192.168.1.21/24
vlan: 100 # VLAN tag for an access port
- name: eth2
addresses:
- 10.12.0.10/16
- 10.12.0.11/16
vlan: 200 # VLAN tag for this interface
routes:
- destination: 0.0.0.0/0
next_hop: 192.168.1.1
- destination: 172.16.0.0/12
next_hop: 10.12.0.254
slack-vm2:
default_gateway: 192.168.1.1
interfaces:
- name: eth0
addresses:
- 192.168.1.22/24
vlan: 100 # VLAN tag for this interface
- name: eth2
addresses:
- 10.12.0.12/16
- 10.12.0.14/16
vlan: 300 # VLAN tag for this interface
routes:
- destination: 10.0.0.0/8
next_hop: 10.12.0.254
@noslin005
Copy link
Author

#!/bin/bash

set -e

# Path to the YAML configuration file
CONFIG_FILE="/etc/network_config.yaml"

# Function to configure an interface
configure_interface() {
    local interface=$1
    local addresses=$2
    local vlan=$3
    local routes=$4

    echo "Configuring interface: $interface"

    # Bring the interface up
    ip link set "$interface" up

    # Configure IP addresses
    if [[ -n "$addresses" ]]; then
        for addr in $addresses; do
            echo "Adding address $addr to $interface"
            ip addr add "$addr" dev "$interface"
        done
    fi

    # Configure VLAN
    if [[ -n "$vlan" ]]; then
        local vlan_iface="${interface}.${vlan}"
        echo "Adding VLAN $vlan to $interface"
        ip link add link "$interface" name "$vlan_iface" type vlan id "$vlan"
        ip link set "$vlan_iface" up
    fi

    # Configure routes
    if [[ -n "$routes" ]]; then
        while IFS= read -r route; do
            local destination=$(echo "$route" | awk '{print $1}')
            local next_hop=$(echo "$route" | awk '{print $2}')
            echo "Adding route to $destination via $next_hop on $interface"
            ip route add "$destination" via "$next_hop" dev "$interface"
        done <<< "$routes"
    fi
}

# Read YAML configuration using yq
vms=$(yq e 'keys | .[]' "$CONFIG_FILE")

for vm in $vms; do
    echo "Configuring VM: $vm"

    # Get the default gateway
    default_gateway=$(yq e ".${vm}.default_gateway" "$CONFIG_FILE")
    if [[ "$default_gateway" != "null" ]]; then
        echo "Setting default gateway: $default_gateway"
        ip route add default via "$default_gateway"
    fi

    # Get the list of interfaces
    interfaces=$(yq e ".${vm}.interfaces[].name" "$CONFIG_FILE")
    for iface in $interfaces; do
        addresses=$(yq e ".${vm}.interfaces[] | select(.name == \"$iface\") | .addresses[]?" "$CONFIG_FILE")
        vlan=$(yq e ".${vm}.interfaces[] | select(.name == \"$iface\") | .vlan?" "$CONFIG_FILE")
        routes=$(yq e -o=tsv ".${vm}.interfaces[] | select(.name == \"$iface\") | .routes[]? | [.destination, .next_hop] | @sh" "$CONFIG_FILE")

        configure_interface "$iface" "$addresses" "$vlan" "$routes"
    done
done

echo "Network configuration complete."

@noslin005
Copy link
Author

#!/usr/bin/env python3

import json
from pathlib import Path
import yaml

def parse_data(file_path):
    """Parse data from the file and return the hosts configuration."""
    try:
        data = Path(file_path).read_text()
    except FileNotFoundError:
        raise FileNotFoundError(f"File not found: {file_path}")
    except Exception as e:
        raise RuntimeError(f"Error reading file: {e}")

    hosts = []
    current_host = None
    host_config = {}

    for line in data.splitlines():
        line = line.strip()

        # Start of a new host block
        if line.startswith("#"):
            current_host = line.lstrip("#").strip()
            host_config = {'hostname': current_host, 'interfaces': []}
            hosts.append(host_config)
            continue

        # Process interface lines
        try:
            interface_name, ip = map(str.strip, line.split(";", maxsplit=1))
        except ValueError:
            raise ValueError(f"Invalid line format: {line}")

        # Check if interface already exists
        interface = next(
            (iface for iface in host_config["interfaces"] if iface["name"] == interface_name),
            None
        )

        if interface is None:
            # Add a new interface
            host_config["interfaces"].append({
                "name": interface_name,
                "addresses": [ip]
            })
        else:
            # Add IP to existing interface
            interface["addresses"].append(ip)

    return hosts

def save_yaml(filename: str, data: list):
    try:
        with open(filename, 'w') as f:
            yaml.safe_dump(data, f, indent=2, sort_keys=False)
    except IOError as e:
        raise RuntimeError('Failed to save yaml file', e.filename, e.strerror)

if __name__ == "__main__":
    file_path = "/tmp/data.txt"
    try:
        hosts = parse_data(file_path)
        print(json.dumps(hosts, indent=2))
        save_yaml('/tmp/data.yml', hosts)
    except Exception as e:
        print(f"Error: {e}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment