mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Add files via upload
This commit is contained in:
69
LibreQoS.py
69
LibreQoS.py
@@ -26,7 +26,8 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from UCRM_Integration import pullUCRMCustomers, getUCRMCaps
|
from UNMS_Integration import pullUNMSCustomers
|
||||||
|
from ispConfig import fqOrCAKE, pipeBandwidthCapacityMbps, interfaceA, interfaceB, enableActualShellCommands, runShellCommandsAsSudo, importFromUNMS
|
||||||
|
|
||||||
def shell(inputCommand):
|
def shell(inputCommand):
|
||||||
if enableActualShellCommands:
|
if enableActualShellCommands:
|
||||||
@@ -66,7 +67,7 @@ def createTestClientsPool(slash16, quantity):
|
|||||||
while mainCounter < quantity:
|
while mainCounter < quantity:
|
||||||
if counterD <= 255:
|
if counterD <= 255:
|
||||||
ipAddr = slash16.replace('X.X', '') + str(counterC) + '.' + str(counterD)
|
ipAddr = slash16.replace('X.X', '') + str(counterC) + '.' + str(counterD)
|
||||||
tempList.append((100, ipAddr))
|
tempList.append((ipAddr, 100, 15))
|
||||||
counterD += 1
|
counterD += 1
|
||||||
else:
|
else:
|
||||||
counterC += 1
|
counterC += 1
|
||||||
@@ -76,63 +77,35 @@ def createTestClientsPool(slash16, quantity):
|
|||||||
else:
|
else:
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
########################################################################################################################################
|
|
||||||
######################################################## ########################################################
|
|
||||||
######################################################## Main Settings ########################################################
|
|
||||||
######################################################## ########################################################
|
|
||||||
########################################################################################################################################
|
|
||||||
|
|
||||||
fqOrCAKE = 'fq_codel' #'fq_codel' or 'cake'
|
|
||||||
# Cake requires many specific packages and kernel changes.
|
|
||||||
# https://www.bufferbloat.net/projects/codel/wiki/Cake/
|
|
||||||
# https://github.com/dtaht/tc-adv
|
|
||||||
pipeBandwidthCapacityMbps = 500 # How many symmetrical Mbps are available to the edge of this test network
|
|
||||||
interfaceA = 'eth4' # Interface connected to edge
|
|
||||||
interfaceB = 'eth5' # Interface connected to core
|
|
||||||
downSpeedDict = {25:30, 50:55, 100:115, 200:215, 300:315} # Define Client Plan download speed. 25, 50, 100 etc are plan identifiers.
|
|
||||||
upSpeedDict = {25:3 , 50:5, 100:15, 200:30, 300:50} # Define Client Plan upload speed
|
|
||||||
enableActualShellCommands = False # Allow shell commands. Default is False; commands print to console.
|
|
||||||
runShellCommandsAsSudo = False # Add 'sudo' before execution of any shell commands. Default is False.
|
|
||||||
importFromUCRM = False # Experimental UCRM integration
|
|
||||||
|
|
||||||
#Clients
|
#Clients
|
||||||
clientsList = []
|
clientsList = []
|
||||||
#Add arbitrary number of test clients in /16 subnet
|
#Add arbitrary number of test clients in /16 subnet
|
||||||
clientsList = createTestClientsPool('100.64.X.X', 5)
|
#clientsList = createTestClientsPool('100.64.X.X', 5)
|
||||||
#Add specific test clients
|
#Add specific test clients
|
||||||
#clientsList.append((100, '100.65.1.1'))
|
#clientsList.append((100, '100.65.1.1'))
|
||||||
|
|
||||||
########################################################################################################################################
|
|
||||||
|
|
||||||
#Bring in clients from UCRM if enabled
|
#Bring in clients from UCRM if enabled
|
||||||
if importFromUCRM:
|
if importFromUNMS:
|
||||||
tempList = pullUCRMCustomers()
|
tempList = pullUNMSCustomers()
|
||||||
for cust in tempList:
|
for cust in tempList:
|
||||||
clientID, ipAddr, download, upload = cust
|
downloadSpeed = cust['downloadSpeed']
|
||||||
#Use UCRM plan speed values to place into corresponding plan defined here in LibreQoS
|
uploadSpeed = cust['uploadSpeed']
|
||||||
if download >= 300:
|
for ipAddr in cust['deviceIPs']:
|
||||||
clientsList.append((300, ipAddr))
|
if '/' in ipAddr:
|
||||||
elif download >= 200:
|
ipAddr = ipAddr.split('/')[0]
|
||||||
clientsList.append((200, ipAddr))
|
#Use UCRM plan speed values to place into corresponding plan defined here in LibreQoS
|
||||||
elif download >= 100:
|
clientsList.append((ipAddr, downloadSpeed, uploadSpeed))
|
||||||
clientsList.append((100, ipAddr))
|
|
||||||
elif download >= 50:
|
|
||||||
clientsList.append((50, ipAddr))
|
|
||||||
elif download >= 25:
|
|
||||||
clientsList.append((25, ipAddr))
|
|
||||||
else:
|
|
||||||
print("Could not match customer ID " + clientID + " with a speed plan. They will be left uncapped.")
|
|
||||||
|
|
||||||
#Categorize Clients By IPv4 /16
|
#Categorize Clients By IPv4 /16
|
||||||
listOfSlash16SubnetsInvolved = []
|
listOfSlash16SubnetsInvolved = []
|
||||||
clientsListWithSubnet = []
|
clientsListWithSubnet = []
|
||||||
for customer in clientsList:
|
for customer in clientsList:
|
||||||
planID, ipAddr = customer
|
ipAddr, downloadSpeed, uploadSpeed = customer
|
||||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||||
slash16 = dec1 + '.' + dec2 + '.0.0'
|
slash16 = dec1 + '.' + dec2 + '.0.0'
|
||||||
if slash16 not in listOfSlash16SubnetsInvolved:
|
if slash16 not in listOfSlash16SubnetsInvolved:
|
||||||
listOfSlash16SubnetsInvolved.append(slash16)
|
listOfSlash16SubnetsInvolved.append(slash16)
|
||||||
clientsListWithSubnet.append((planID, ipAddr, slash16, dec1, dec2, dec3, dec4))
|
clientsListWithSubnet.append((ipAddr, downloadSpeed, uploadSpeed, slash16, dec1, dec2, dec3, dec4))
|
||||||
#Clear Prior Configs
|
#Clear Prior Configs
|
||||||
clearPriorSettings(interfaceA, interfaceB)
|
clearPriorSettings(interfaceA, interfaceB)
|
||||||
#InterfaceA
|
#InterfaceA
|
||||||
@@ -150,7 +123,7 @@ for slash16 in listOfSlash16SubnetsInvolved:
|
|||||||
for i in range(255):
|
for i in range(255):
|
||||||
tempList = []
|
tempList = []
|
||||||
for customer in clientsListWithSubnet:
|
for customer in clientsListWithSubnet:
|
||||||
planID, ipAddr, slash16, dec1, dec2, dec3, dec4 = customer
|
ipAddr, downloadSpeed, uploadSpeed, slash16, dec1, dec2, dec3, dec4 = customer
|
||||||
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
||||||
tempList.append(customer)
|
tempList.append(customer)
|
||||||
if len(tempList) > 0:
|
if len(tempList) > 0:
|
||||||
@@ -164,9 +137,9 @@ for slash16 in listOfSlash16SubnetsInvolved:
|
|||||||
currentCustomerList = groupedCustomers.pop()
|
currentCustomerList = groupedCustomers.pop()
|
||||||
tempHashList = getHashList()
|
tempHashList = getHashList()
|
||||||
for cust in currentCustomerList:
|
for cust in currentCustomerList:
|
||||||
planID, ipAddr, slash16, dec1, dec2, dec3, dec4 = cust
|
ipAddr, downloadSpeed, uploadSpeed, slash16, dec1, dec2, dec3, dec4 = cust
|
||||||
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
||||||
shell('tc class add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(downSpeedDict[planID]) + 'mbit ceil '+ str(downSpeedDict[planID]) + 'mbit prio 3')
|
shell('tc class add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(downloadSpeed) + 'mbit ceil '+ str(downloadSpeed) + 'mbit prio 3')
|
||||||
shell('tc qdisc add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
shell('tc qdisc add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||||
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
||||||
classIDCounter += 1
|
classIDCounter += 1
|
||||||
@@ -191,7 +164,7 @@ for slash16 in listOfSlash16SubnetsInvolved:
|
|||||||
for i in range(255):
|
for i in range(255):
|
||||||
tempList = []
|
tempList = []
|
||||||
for customer in clientsListWithSubnet:
|
for customer in clientsListWithSubnet:
|
||||||
planID, ipAddr, slash16, dec1, dec2, dec3, dec4 = customer
|
ipAddr, downloadSpeed, uploadSpeed, slash16, dec1, dec2, dec3, dec4 = customer
|
||||||
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
||||||
tempList.append(customer)
|
tempList.append(customer)
|
||||||
if len(tempList) > 0:
|
if len(tempList) > 0:
|
||||||
@@ -205,9 +178,9 @@ for slash16 in listOfSlash16SubnetsInvolved:
|
|||||||
currentCustomerList = groupedCustomers.pop()
|
currentCustomerList = groupedCustomers.pop()
|
||||||
tempHashList = getHashList()
|
tempHashList = getHashList()
|
||||||
for cust in currentCustomerList:
|
for cust in currentCustomerList:
|
||||||
planID, ipAddr, slash16, dec1, dec2, dec3, dec4 = cust
|
ipAddr, downloadSpeed, uploadSpeed, slash16, dec1, dec2, dec3, dec4 = cust
|
||||||
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
||||||
shell('tc class add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(upSpeedDict[planID]) + 'mbit ceil '+ str(upSpeedDict[planID]) + 'mbit prio 3')
|
shell('tc class add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(uploadSpeed) + 'mbit ceil '+ str(uploadSpeed) + 'mbit prio 3')
|
||||||
shell('tc qdisc add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
shell('tc qdisc add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||||
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
||||||
classIDCounter += 1
|
classIDCounter += 1
|
||||||
|
|||||||
85
UNMS_Integration.py
Normal file
85
UNMS_Integration.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Copyright (C) 2020 Robert Chacón
|
||||||
|
# This file is part of LibreQoS.
|
||||||
|
#
|
||||||
|
# LibreQoS is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# LibreQoS is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with LibreQoS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# _ _ _ ___ ____
|
||||||
|
# | | (_) |__ _ __ ___ / _ \ ___/ ___|
|
||||||
|
# | | | | '_ \| '__/ _ \ | | |/ _ \___ \
|
||||||
|
# | |___| | |_) | | | __/ |_| | (_) |__) |
|
||||||
|
# |_____|_|_.__/|_| \___|\__\_\\___/____/
|
||||||
|
# v.0.3-alpha
|
||||||
|
#
|
||||||
|
import requests
|
||||||
|
from ispConfig import orgUNMSxAuthToken, unmsBaseURL
|
||||||
|
|
||||||
|
#To omit bridged CPEs from shaping
|
||||||
|
#deviceModelBlacklist = ['Litebeam AC Gen2', 'LTU Pro', 'LTU LR']
|
||||||
|
deviceModelBlacklist = []
|
||||||
|
|
||||||
|
def pullUNMSCustomers():
|
||||||
|
url = unmsBaseURL + "/nms/api/v2.1/sites?type=client&ucrm=true&ucrmDetails=true"
|
||||||
|
headers = {'accept':'application/json', 'x-auth-token': orgUNMSxAuthToken}
|
||||||
|
r = requests.get(url, headers=headers)
|
||||||
|
jsonData = r.json()
|
||||||
|
#print(jsonData)
|
||||||
|
unmsCustomers = []
|
||||||
|
for unmsClientSite in jsonData:
|
||||||
|
downloadSpeedMbps = int(round(unmsClientSite['qos']['downloadSpeed']/1000000))
|
||||||
|
uploadSpeedMbps = int(round(unmsClientSite['qos']['uploadSpeed']/1000000))
|
||||||
|
address = unmsClientSite['description']['address']
|
||||||
|
unmsClientSiteID = unmsClientSite['id']
|
||||||
|
deviceList = getUNMSclientSiteDevices(unmsClientSiteID)
|
||||||
|
thisCustomer = {
|
||||||
|
'address' : address,
|
||||||
|
'downloadSpeed' : downloadSpeedMbps,
|
||||||
|
'uploadSpeed' : uploadSpeedMbps,
|
||||||
|
}
|
||||||
|
for device in deviceList:
|
||||||
|
thisCustomer['deviceIPs'] = deviceList
|
||||||
|
unmsCustomers.append(thisCustomer)
|
||||||
|
return unmsCustomers
|
||||||
|
|
||||||
|
def getUNMSclientSiteDevices(siteID):
|
||||||
|
url = unmsBaseURL + "/nms/api/v2.1/devices?siteId=" + siteID
|
||||||
|
headers = {'accept':'application/json', 'x-auth-token': orgUNMSxAuthToken}
|
||||||
|
r = requests.get(url, headers=headers)
|
||||||
|
jsonData = r.json()
|
||||||
|
deviceIPs = []
|
||||||
|
for device in jsonData:
|
||||||
|
deviceName = device['identification']['name']
|
||||||
|
deviceMAC = device['identification']['mac']
|
||||||
|
deviceIP = device['ipAddress']
|
||||||
|
deviceModel = device['identification']['model']
|
||||||
|
if deviceModel not in deviceModelBlacklist:
|
||||||
|
deviceIPs.append(deviceIP)
|
||||||
|
return deviceIPs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
29
ispConfig.py
Normal file
29
ispConfig.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#'fq_codel' or 'cake'
|
||||||
|
# Cake requires many specific packages and kernel changes:
|
||||||
|
# https://www.bufferbloat.net/projects/codel/wiki/Cake/
|
||||||
|
# https://github.com/dtaht/tc-adv
|
||||||
|
fqOrCAKE = 'fq_codel'
|
||||||
|
|
||||||
|
# How many symmetrical Mbps are available to the edge of this test network
|
||||||
|
pipeBandwidthCapacityMbps = 500
|
||||||
|
|
||||||
|
# Interface connected to edge
|
||||||
|
interfaceA = 'eth4'
|
||||||
|
|
||||||
|
# Interface connected to core
|
||||||
|
interfaceB = 'eth5'
|
||||||
|
|
||||||
|
# Allow shell commands. Default is False where commands print to console. Must be enabled to function
|
||||||
|
enableActualShellCommands = False
|
||||||
|
|
||||||
|
# Add 'sudo' before execution of any shell commands. Default is False.
|
||||||
|
runShellCommandsAsSudo = False
|
||||||
|
|
||||||
|
# Import customer QoS rules from UNMS
|
||||||
|
importFromUNMS = False
|
||||||
|
|
||||||
|
# Available under UNMS > Settings > Users
|
||||||
|
orgUNMSxAuthToken = ''
|
||||||
|
|
||||||
|
# Everything before /nms/. Use https:// For example: https://unms.exampleISP.com (no slash after)
|
||||||
|
unmsBaseURL = ''
|
||||||
Reference in New Issue
Block a user