ORIGINAL PROJECT INTERFACE · GrandStay · original Python source; no devices connected · Fictional demo data · Back to portfolio

vlan_automation.py

Original automation module from the submitted project. Lab credentials and the device inventory are not published.

# vlan_automation.py
# Layer 2 VLAN Provisioning Loop
# Pushes the global VLAN database to every switch in the topology, then applies
# role-specific access-port VLAN assignments based on which block/device type
# each access switch actually serves (Staff, Management, or Guest).

from netmiko import ConnectHandler
from devices import INVENTORY, VLAN_CONFIGS

# Maps each access-layer role to the VLAN its connected end devices belong to,
# based on the Packet Tracer topology (Figure 3.1).
ROLE_VLAN_ASSIGNMENT = {
    "access_staff_backoffice": 10,  # ACC-BACK -> Staff PCs, laptops, AP
    "access_staff": 10,             # ACC-STAFF -> Staff PCs, laptops, AP
    "access_mgmt": 20,              # ACC-FRONTDESK -> Management / front desk devices
    "access_guest": 30,             # ACC-GUEST -> Guest TVs, smartphones, AP
}


def provision_vlans():
    print("[*] Initiating Layer 2 VLAN Automation Broadcast...")
    for device in INVENTORY["switches"]:
        try:
            print(f"[+] Establishing SSH Connection to {device['name']} ({device['block']} Block) "
                  f"at {device['host']}")
            net_connect = ConnectHandler(**{
                k: v for k, v in device.items() if k not in ("role", "name", "block")
            })

            # Global VLAN database compilation - every switch gets the full VLAN set
            net_connect.send_config_set(VLAN_CONFIGS)
            print(f"[SUCCESS] VLAN database synchronized on {device['name']}\n")

            # Apply access-port VLAN assignment if this device has an access-layer role
            vlan_id = ROLE_VLAN_ASSIGNMENT.get(device["role"])
            if vlan_id:
                commands = []
                for port_num in range(1, 5):
                    commands.extend([
                        f"interface GigabitEthernet0/{port_num}",
                        "switchport mode access",
                        f"switchport access vlan {vlan_id}",
                        "spanning-tree portfast"
                    ])
                net_connect.send_config_set(commands)
                print(f"[SUCCESS] Access ports on {device['name']} assigned to VLAN {vlan_id} "
                      f"({device['block']} Block)")

            net_connect.disconnect()
        except Exception as e:
            print(f"[ERROR] Failed configuration on device {device['name']} "
                  f"({device['host']}): {str(e)}")


if __name__ == "__main__":
    provision_vlans()