Skip to content

Instantly share code, notes, and snippets.

@stif
Created October 27, 2023 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stif/7530c9234fd5b1343539e840b8d2eeb2 to your computer and use it in GitHub Desktop.
Save stif/7530c9234fd5b1343539e840b8d2eeb2 to your computer and use it in GitHub Desktop.
Unifi VLAN Creation Automation

Selenium Webdriver

with Selenium Webdriver you can automate tasks on a webpage. In this Scenario Selenium opens chromium webbroser, Logs into the Unifi Controller WebUI, read the config.csv file and add a VLAN for every Line in the CSV File.

npm install
USER=myUnifiUser PASS=myUnifiPass node index.js
create Vlan: V13-VLAN13 Name
create Vlan: V14-VLAN14 Name
...
VLAN Beschreibung
13 VLAN13 Name
14 VLAN14 Name
15 VLAN15 Name
16 VLAN16 Name
17 VLAN17 Name
18 VLAN18 Name
const csv = require('csv-parser');
const fs = require('fs');
const { Builder, By, Key, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
let options = new chrome.Options();
options.addArguments('ignore-certificate-errors'); // Zertifikatswarnungen ignorieren
options.setPageLoadStrategy('normal');
const USER = process.env.USER || "maintain";
const PASS = process.env.PASS || "pass";
const URL = process.env.URL || "https://10.1.1.50:30072/"
async function createVLANs(vlanData) {
let driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build();
try {
await driver.get( URL + 'manage/account/login');
// Einloggen
//const usernameInput = await driver.wait(until.elementIsVisible(driver.findElement(By.name('username'))), 10000);
//await usernameInput.sendKeys('IhrUsername');
//await driver.wait(until.elementLocated(By.css('input#username')), 10000);
//await driver.findElement(By.css('input#username')).sendKeys('maintain');
//await driver.findElement(By.id('username')).sendKeys('maintain');
//await driver.executeScript(`document.querySelector("input[name='username']").value = 'maintain';`);
await driver.wait(until.elementLocated(By.name('username')), 10000);
await driver.findElement(By.name('username')).sendKeys(USER);
await driver.findElement(By.name('password')).sendKeys(PASS, Key.RETURN);
// Warten, bis das Dashboard geladen ist
await driver.wait(until.titleIs('UniFi Network'), 10000); // Ändern Sie den Titel entsprechend
await driver.sleep(1000); // 1 Sekunden warten
//await driver.get( URL + 'manage/default/settings/wifi');
await driver.get( URL + 'manage/default/settings/networks');
await driver.wait(until.elementLocated(By.css('[data-testid="networks"]')));
for (let data of vlanData) {
// Verwenden Sie 'data' hier, um auf die einzelnen CSV-Felder zuzugreifen
// z.B. data.VLAN, data.Beschreibung, etc.
vlanName = `V${data.VLAN}-${data.Beschreibung}`
console.log("create Vlan: " + vlanName)
//<button name="networks-create" type="button" class="button__jTNy2Cxe button-light__jTNy2Cxe inline__jTNy2Cxe inline-light__jTNy2Cxe small__jTNy2Cxe"><span class="content__jTNy2Cxe"><span class="text-base__f7qlgEeP text-size-body__f7qlgEeP text-light-inherit__f7qlgEeP text-weight-normal__f7qlgEeP">New Virtual Network</span></span><div class="stateIcon__jTNy2Cxe"></div></button>
//await driver.wait(until.elementLocated(By.name('networks-create')), 10000);
//await driver.findElement(By.name('networks-create')).click();
await driver.wait(until.elementLocated(By.name('networks-create')), 10000);
let createNetworkButton = await driver.findElement(By.name('networks-create'));
await driver.executeScript("arguments[0].scrollIntoView(true);", createNetworkButton); // falls liste zu lang scrolle zu "createNetworkbutton"
await driver.sleep(500); // Kurze Wartezeit, um das Scrollen abzuschließen
createNetworkButton.click();
//<input autocomplete="off" data-lpignore="true" name="name" id="name" type="text" class="input__Ik1LObH5 input-secondary__Ik1LObH5 input-light__Ik1LObH5 input-body__Ik1LObH5 input-body-secondary__Ik1LObH5 input-invalid-light__Ik1LObH5" value="">
await driver.wait(until.elementLocated(By.id('name')), 10000);
await driver.findElement(By.id('name')).sendKeys(vlanName);
//<input autocomplete="off" data-lpignore="true" name="thirdPartyVlan" id="thirdPartyVlan" type="number" class="input__Ik1LObH5 input-secondary__Ik1LObH5 input-light__Ik1LObH5 input-body__Ik1LObH5 input-body-secondary__Ik1LObH5 input-invalid-light__Ik1LObH5" value="">
await driver.findElement(By.id('thirdPartyVlan')).sendKeys(data.VLAN);
await driver.sleep(2000)
//<button type="button" class="button__jTNy2Cxe button-light__jTNy2Cxe default__jTNy2Cxe default-light__jTNy2Cxe medium__jTNy2Cxe formFooterButton-default-size-medium__HDgxE3Ld"><span class="content__jTNy2Cxe">Cancel</span><div class="stateIcon__jTNy2Cxe"></div></button>
//await driver.findElement(By.xpath("//button[span[contains(text(), 'Cancel')]]")).click();
//<button type="submit" class="button__jTNy2Cxe button-light__jTNy2Cxe primary__jTNy2Cxe primary-light__jTNy2Cxe medium__jTNy2Cxe"><span class="content__jTNy2Cxe">Add</span><div class="stateIcon__jTNy2Cxe"></div></button>
await driver.findElement(By.xpath("//button[span[contains(text(), 'Add')]]")).click();
await driver.sleep(2000); // 2 Sekunden warten zwischen den Aktionen
}
} finally {
await driver.sleep(5000)
await driver.quit();
console.log("finished")
}
}
function readCSV(filename) {
return new Promise((resolve, reject) => {
let results = [];
fs.createReadStream(filename)
.pipe(csv())
.on('data', (data) => results.push(data))
.on('end', () => {
resolve(results);
})
.on('error', reject);
});
}
readCSV('config.csv').then((data) => {
createVLANs(data);
}).catch(console.error);
{
"dependencies": {
"chromedriver": "^117.0.3",
"csv-parser": "^3.0.0",
"selenium-webdriver": "^4.13.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment