Who Says Geeks Can't Have Fun? 🌝
Happy Hump Day, fellow network warriors!
You know what's fun? Solving challenges that make other engineers cry. And we have fun every single day doing exactly that. 😊
Today, I want to share how we turned what could have been a mind-numbing, error-prone, 4-day manual migration into an elegant automated solution. Because life's too short to click buttons 1,000 times.
The Challenge: When APIs Don't Exist
Picture this scenario:
- Customer needs: Migrate from Cisco Umbrella to Cisco Secure Access
- Objects to migrate: ~1,000 application list entries + ~1,000 do-not-decrypt list entries
- Available APIs: None. Zip. Nada.
- Manual effort required: 3-4 days of mind-numbing clicking
- Error probability: Through the roof 😭
Here's the kicker: Cisco Secure Access doesn't have APIs for all configuration objects. No APIs for application lists. No APIs for do-not-decrypt lists. Just a web portal and the expectation that you'll manually enter everything.
The Crossroads: Manual Pain or Creative Gain?
We could have gone the manual route. I mean, that's what most people would do, right?
Manual Migration Math:
- 2,000 entries total
- ~2 minutes per entry (navigate, enter, verify, save)
- = 4,000 minutes
- = 67 hours
- = 3-4 days of pure tedium
And that's assuming:
- No typos
- No missed entries
- No fatigue-induced errors
- No desire to throw your laptop out the window
But here's the thing: My team and I aren't "most people." We're here to give clients the best possible outcome. And clicking buttons for 4 days? That's not it.
The Solution: Selenium to the Rescue
Enter the magic of the selenium
module with Python—the tool that lets you automate web browsers like a puppet master.
Instead of manually clicking and typing, we built a script that:
- Reads the exported Umbrella configuration
- Navigates the Cisco Secure Access portal
- Clicks the right buttons
- Fills in the right fields
- Saves each entry
- Verifies the upload
All while we grab coffee and watch it work. ☕
The Technical Magic: How It Works
Here's our solution blueprint:
Step 1: Export from Umbrella
# Download configuration from Cisco Umbrella
# Format: JSON with all application lists and do-not-decrypt lists
Step 2: The Selenium Automation Script
Here's a simplified version of what we built:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
import time
def migrate_to_secure_access(json_file):
"""
Automates migration of Umbrella configs to Secure Access
"""
# Load the exported data
with open(json_file, 'r') as f:
umbrella_data = json.load(f)
# Initialize the browser
driver = webdriver.Chrome()
driver.get("https://secure-access.cisco.com")
# Login process (simplified)
login_to_portal(driver)
# Navigate to application lists
navigate_to_app_lists(driver)
# Process each application entry
for app in umbrella_data['application_lists']:
add_application_entry(driver, app)
time.sleep(0.5) # Be nice to the server
# Navigate to do-not-decrypt lists
navigate_to_dnd_lists(driver)
# Process each DND entry
for dnd in umbrella_data['do_not_decrypt_lists']:
add_dnd_entry(driver, dnd)
time.sleep(0.5)
print(f"Migration complete! Processed {len(umbrella_data)} entries")
def add_application_entry(driver, app_data):
"""
Adds a single application entry via web automation
"""
# Click "Add" button
add_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "add-application"))
)
add_btn.click()
# Fill in the form
name_field = driver.find_element(By.ID, "app-name")
name_field.send_keys(app_data['name'])
url_field = driver.find_element(By.ID, "app-url")
url_field.send_keys(app_data['url'])
# Save
save_btn = driver.find_element(By.ID, "save-button")
save_btn.click()
Step 3: Verification Script
Trust, but verify. Always.
def verify_migration(driver, original_data):
"""
Verifies all entries were migrated successfully
"""
migrated_apps = fetch_all_applications(driver)
migrated_dnd = fetch_all_dnd_entries(driver)
# Compare counts
print(f"Original apps: {len(original_data['application_lists'])}")
print(f"Migrated apps: {len(migrated_apps)}")
# Check for missing entries
missing = find_missing_entries(original_data, migrated_apps)
if missing:
print(f"Warning: {len(missing)} entries failed to migrate")
return False
print("✅ All entries migrated successfully!")
return True
The Results: Time is Money (And Sanity)
Let's talk ROI:
Development Time:
- Coding: ~8 hours
- Testing: ~3 hours
- Verification: ~1 hour
- Total: 12 hours
Time Saved Per Migration:
- Manual process: 67 hours
- Automated process: 2 hours
- Saved: 65 hours per customer
For Multiple Customers:
- 10 customers = 650 hours saved
- 20 customers = 1,300 hours saved
- That's literally months of productive time returned! 💯
Lessons Learned: When Life Gives You No APIs...
1. Think Outside the API Box
Just because there's no API doesn't mean you're stuck with manual work. Web automation can be a lifesaver when official integration methods don't exist.
2. Always Factor in Testing Time
Yes, it took 12 hours to build. But those 12 hours prevent countless errors and save hundreds of hours down the line. That's not a cost—that's an investment.
3. Verify Everything
Automation without verification is just automated chaos. Always build in checks to ensure your automation actually worked.
4. Document Your Automation
Future you (or your teammates) will thank present you for clear documentation. Our script includes detailed comments and error handling for every edge case we encountered.
The Bigger Picture: Automation Mindset
This project embodies a core philosophy: Always look for the multiplier effect.
Sure, we could have done this migration manually. Once. But we're not in the business of doing things once. We're in the business of solving problems at scale.
Every hour spent on automation is an hour that pays dividends across every future migration. It's the difference between working hard and working smart.
Your Turn: What Would You Automate?
I'm curious—what manual, repetitive tasks are eating up your time? What processes make you think, "There has to be a better way"?
Maybe it's configuration management. Maybe it's report generation. Maybe it's something nobody else has even thought to automate yet.
Drop a comment below and let's brainstorm. Sometimes the best solutions come from engineers sharing their pain points.
Ready to Migrate?
If you're facing a Cisco Umbrella to Cisco Secure Access migration (or any similar challenge), we're here to help. Why spend days clicking when you could be solving more interesting problems?
Remember: Geeks can have fun. Especially when that fun involves making tedious tasks disappear. 🚀
P.S. - Interested in the full script? Reach out. We love sharing tools that make engineers' lives easier. After all, we're all in this together!