Add files via upload

This commit is contained in:
rchac 2021-01-10 13:21:46 -07:00 committed by GitHub
parent 92c33b7054
commit ff0e55b56b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 217 additions and 265 deletions

View File

@ -19,241 +19,231 @@
# | | | | '_ \| '__/ _ \ | | |/ _ \___ \
# | |___| | |_) | | | __/ |_| | (_) |__) |
# |_____|_|_.__/|_| \___|\__\_\\___/____/
# v.0.71-alpha
# v.0.75-alpha
#
import random
import logging
import os
import io
import json
import csv
import subprocess
from subprocess import PIPE
import ipaddress
from ipaddress import IPv4Address, IPv6Address
import time
from datetime import date, datetime
from UNMS_Integration import pullUNMSDevices
from LibreNMS_Integration import pullLibreNMSDevices
from ispConfig import fqOrCAKE, pipeBandwidthCapacityMbps, interfaceA, interfaceB, addTheseSubnets, enableActualShellCommands, runShellCommandsAsSudo, importFromUNMS, importFromLibreNMS
from ispConfig import fqOrCAKE, pipeBandwidthCapacityMbps, interfaceA, interfaceB, enableActualShellCommands, runShellCommandsAsSudo
def shell(inputCommand):
def shell(command):
if enableActualShellCommands:
if runShellCommandsAsSudo:
inputCommand = 'sudo ' + inputCommand
inputCommandSplit = inputCommand.split(' ')
print(inputCommand)
result = subprocess.run(inputCommandSplit, stdout=subprocess.PIPE)
print(result.stdout)
command = 'sudo ' + command
commands = command.split(' ')
print(command)
proc = subprocess.Popen(commands, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"): # or another encoding
print(line)
else:
print(inputCommand)
print(command)
def clearMemoryCache():
command = "sudo sh -c 'echo 1 >/proc/sys/vm/drop_caches'"
commands = command.split(' ')
proc = subprocess.Popen(commands, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
print(line)
def clearPriorSettings(interfaceA, interfaceB):
shell('tc filter delete dev ' + interfaceA)
shell('tc filter delete dev ' + interfaceA + ' root')
shell('tc qdisc delete dev ' + interfaceA)
shell('tc qdisc delete dev ' + interfaceA + ' root')
shell('tc qdisc delete dev ' + interfaceA)
shell('tc filter delete dev ' + interfaceB)
shell('tc filter delete dev ' + interfaceB + ' root')
shell('tc qdisc delete dev ' + interfaceB + ' root')
shell('tc qdisc delete dev ' + interfaceB)
shell('tc qdisc delete dev ' + interfaceB + ' root')
def getHashList():
twoDigitHash = []
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
for i in range(10):
for x in range(26):
twoDigitHash.append(str(i) + letters[x])
return twoDigitHash
def addCustomersBySubnet(inputBlock):
addTheseSubnets, existingShapableDevices = inputBlock
customersToAdd = []
for subnetItem in addTheseSubnets:
ipcidr, downloadMbps, uploadMbps = subnetItem
theseHosts = list(ipaddress.ip_network(ipcidr).hosts())
for host in theseHosts:
deviceIP = str(host)
alreadyAssigned = False
for device in existingShapableDevices:
if deviceIP == device['identification']['ipAddr']:
alreadyAssigned = True
if not alreadyAssigned:
thisShapedDevice = {
"identification": {
"name": None,
"hostname": None,
"ipAddr": deviceIP,
"mac": None,
"model": None,
"modelName": None,
"unmsSiteID": None,
"libreNMSSiteID": None
},
"qos": {
"downloadMbps": downloadMbps,
"uploadMbps": uploadMbps,
"accessPoint": None
},
}
customersToAdd.append(thisShapedDevice)
return customersToAdd
if runShellCommandsAsSudo:
clearMemoryCache()
def refreshShapers():
#Clients
shapableDevices = []
#Bring in clients from UNMS or LibreNMS if enabled
if importFromUNMS:
shapableDevices.extend(pullUNMSDevices())
if importFromLibreNMS:
shapableDevices.extend(pullLibreNMSDevices())
#Add customers by subnet. Will not replace those that already exist
if addTheseSubnets:
shapableDevices.extend(addCustomersBySubnet((addTheseSubnets, shapableDevices)))
#Categorize Clients By IPv4 /16
listOfSlash16SubnetsInvolved = []
shapableDevicesListWithSubnet = []
for device in shapableDevices:
ipAddr = device['identification']['ipAddr']
dec1, dec2, dec3, dec4 = ipAddr.split('.')
slash16 = dec1 + '.' + dec2 + '.0.0'
if slash16 not in listOfSlash16SubnetsInvolved:
listOfSlash16SubnetsInvolved.append(slash16)
shapableDevicesListWithSubnet.append((ipAddr))
devices = []
filterHandleCounter = 101
#Load Devices
with open('Shaper.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
next(csv_reader)
for row in csv_reader:
deviceID, hostname, ipv4, ipv6, download, upload = row
thisDevice = {
"id": deviceID,
"hostname": hostname,
"ipv4": ipv4,
"ipv6": ipv6,
"download": int(download),
"upload": int(upload),
"qdiscSrc": '',
"qdiscDst": '',
}
devices.append(thisDevice)
#Clear Prior Configs
clearPriorSettings(interfaceA, interfaceB)
shell('tc filter delete dev ' + interfaceA + ' parent 1: u32')
shell('tc filter delete dev ' + interfaceB + ' parent 2: u32')
ipv4FiltersSrc = []
ipv4FiltersDst = []
ipv6FiltersSrc = []
ipv6FiltersDst = []
#InterfaceA
parentIDFirstPart = 1
srcOrDst = 'dst'
thisInterface = interfaceA
classIDCounter = 101
hashIDCounter = parentIDFirstPart + 1
shell('tc qdisc replace dev ' + interfaceA + ' root handle ' + str(parentIDFirstPart) + ': htb default 1')
shell('tc class add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
for slash16 in listOfSlash16SubnetsInvolved:
#X.X.0.0
thisSlash16Dec1 = slash16.split('.')[0]
thisSlash16Dec2 = slash16.split('.')[1]
groupedCustomers = []
for i in range(256):
tempList = []
for ipAddr in shapableDevicesListWithSubnet:
dec1, dec2, dec3, dec4 = ipAddr.split('.')
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
tempList.append(ipAddr)
if len(tempList) > 0:
groupedCustomers.append(tempList)
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32')
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 handle ' + str(hashIDCounter) + ': u32 divisor 256')
thirdDigitCounter = 0
handleIDSecond = 1
while thirdDigitCounter <= 255:
if len(groupedCustomers) > 0:
currentIPList = groupedCustomers.pop()
tempHashList = getHashList()
for ipAddr in currentIPList:
for device in shapableDevices:
if device['identification']['ipAddr'] == ipAddr:
downloadSpeed = device['qos']['downloadMbps']
uploadSpeed = device['qos']['uploadMbps']
dec1, dec2, dec3, dec4 = ipAddr.split('.')
twoDigitHashString = hex(int(dec4)).replace('0x','')
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 filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
for device in shapableDevices:
if device['identification']['ipAddr'] == ipAddr:
if srcOrDst == 'src':
qdiscDict ={'qDiscSrc': deviceQDiscID}
elif srcOrDst == 'dst':
qdiscDict ={'qDiscDst': deviceQDiscID}
device['identification'].update(qdiscDict)
classIDCounter += 1
thirdDigitCounter += 1
if (srcOrDst == 'dst'):
startPointForHash = '16' #Position of dst-address in IP header
elif (srcOrDst == 'src'):
startPointForHash = '12' #Position of src-address in IP header
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht 800:: match ip ' + srcOrDst + ' '+ thisSlash16Dec1 + '.' + thisSlash16Dec2 + '.0.0/16 hashkey mask 0x000000ff at ' + startPointForHash + ' link ' + str(hashIDCounter) + ':')
hashIDCounter += 1
shell('tc qdisc replace dev ' + thisInterface + ' root handle ' + str(parentIDFirstPart) + ': htb default 15')
shell('tc class add dev ' + thisInterface + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
shell('tc qdisc add dev ' + thisInterface + ' parent 1:1 fq_codel')
#Default class - traffic gets passed through this limiter if not otherwise classified by the Shaper.csv
shell('tc class add dev ' + thisInterface + ' parent 1:1 classid 1:15 htb rate 750mbit ceil 750mbit prio 5')
shell('tc qdisc add dev ' + thisInterface + ' parent 1:15 fq_codel')
handleIDSecond = 1
for device in devices:
speedcap = 0
if srcOrDst == 'dst':
speedcap = device['download']
elif srcOrDst == 'src':
speedcap = device['upload']
#Create Hash Table
shell('tc class add dev ' + thisInterface + ' parent 1:1 classid 1:' + str(classIDCounter) + ' htb rate '+ str(speedcap) + 'mbit ceil '+ str(round(speedcap*1.1)) + 'mbit prio 3')
shell('tc qdisc add dev ' + thisInterface + ' parent 1:' + str(classIDCounter) + ' ' + fqOrCAKE)
if device['ipv4']:
parentString = '1:'
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
ipv4FiltersDst.append((device['ipv4'], parentString, flowIDstring))
if device['ipv6']:
parentString = '1:'
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
ipv6FiltersDst.append((device['ipv6'], parentString, flowIDstring))
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
if srcOrDst == 'src':
device['qdiscSrc'] = deviceQDiscID
elif srcOrDst == 'dst':
device['qdiscDst'] = deviceQDiscID
classIDCounter += 1
hashIDCounter += 1
#InterfaceB
parentIDFirstPart = hashIDCounter + 1
hashIDCounter = parentIDFirstPart + 1
parentIDFirstPart = 2
srcOrDst = 'src'
shell('tc qdisc replace dev ' + interfaceB + ' root handle ' + str(parentIDFirstPart) + ': htb default 1')
shell('tc class add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
for slash16 in listOfSlash16SubnetsInvolved:
#X.X.0.0
thisSlash16Dec1 = slash16.split('.')[0]
thisSlash16Dec2 = slash16.split('.')[1]
groupedCustomers = []
for i in range(256):
tempList = []
for ipAddr in shapableDevicesListWithSubnet:
dec1, dec2, dec3, dec4 = ipAddr.split('.')
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
tempList.append(ipAddr)
if len(tempList) > 0:
groupedCustomers.append(tempList)
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32')
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 handle ' + str(hashIDCounter) + ': u32 divisor 256')
thirdDigitCounter = 0
handleIDSecond = 1
while thirdDigitCounter <= 255:
if len(groupedCustomers) > 0:
currentIPList = groupedCustomers.pop()
tempHashList = getHashList()
for ipAddr in currentIPList:
for device in shapableDevices:
if device['identification']['ipAddr'] == ipAddr:
downloadSpeed = device['qos']['downloadMbps']
uploadSpeed = device['qos']['uploadMbps']
dec1, dec2, dec3, dec4 = ipAddr.split('.')
twoDigitHashString = hex(int(dec4)).replace('0x','')
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 filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
for device in shapableDevices:
if device['identification']['ipAddr'] == ipAddr:
if srcOrDst == 'src':
qdiscDict ={'qDiscSrc': deviceQDiscID}
elif srcOrDst == 'dst':
qdiscDict ={'qDiscDst': deviceQDiscID}
device['identification'].update(qdiscDict)
classIDCounter += 1
thirdDigitCounter += 1
if (srcOrDst == 'dst'):
startPointForHash = '16' #Position of dst-address in IP header
elif (srcOrDst == 'src'):
startPointForHash = '12' #Position of src-address in IP header
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht 800:: match ip ' + srcOrDst + ' '+ thisSlash16Dec1 + '.' + thisSlash16Dec2 + '.0.0/16 hashkey mask 0x000000ff at ' + startPointForHash + ' link ' + str(hashIDCounter) + ':')
hashIDCounter += 1
thisInterface = interfaceB
classIDCounter = 101
hashIDCounter = parentIDFirstPart + 1
shell('tc qdisc replace dev ' + thisInterface + ' root handle ' + str(parentIDFirstPart) + ': htb default 15')
shell('tc class add dev ' + thisInterface + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
#Default class - traffic gets passed through this limiter if not otherwise classified by the Shaper.csv
shell('tc class add dev ' + thisInterface + ' parent 2:1 classid 2:15 htb rate 750mbit ceil 750mbit prio 5')
shell('tc qdisc add dev ' + thisInterface + ' parent 2:15 fq_codel')
handleIDSecond = 1
for device in devices:
speedcap = 0
if srcOrDst == 'dst':
speedcap = device['download']
elif srcOrDst == 'src':
speedcap = device['upload']
#Create Hash Table
shell('tc class add dev ' + thisInterface + ' parent 2:1 classid 2:' + str(classIDCounter) + ' htb rate '+ str(speedcap) + 'mbit ceil '+ str(round(speedcap*1.1)) + 'mbit prio 3')
shell('tc qdisc add dev ' + thisInterface + ' parent 2:' + str(classIDCounter) + ' ' + fqOrCAKE)
if device['ipv4']:
parentString = '2:'
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
ipv4FiltersSrc.append((device['ipv4'], parentString, flowIDstring))
if device['ipv6']:
parentString = '2:'
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
ipv6FiltersSrc.append((device['ipv6'], parentString, flowIDstring))
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
if srcOrDst == 'src':
device['qdiscSrc'] = deviceQDiscID
elif srcOrDst == 'dst':
device['qdiscDst'] = deviceQDiscID
classIDCounter += 1
hashIDCounter += 1
shell('tc filter add dev ' + interfaceA + ' parent 1: protocol all u32')
shell('tc filter add dev ' + interfaceB + ' parent 2: protocol all u32')
#Save shapableDevices to file to allow for debugging and statistics runs
with open('shapableDevices.json', 'w') as outfile:
json.dump(shapableDevices, outfile)
#IPv4 Hash Filters
#Dst
interface = interfaceA
shell('tc filter add dev ' + interface + ' parent 1: protocol ip handle 3: u32 divisor 256')
for i in range (256):
hexID = str(hex(i)).replace('0x','')
for ipv4Filter in ipv4FiltersDst:
ipv4, parent, classid = ipv4Filter
if '/' in ipv4:
ipv4 = ipv4.split('/')[0]
if (ipv4.split('.', 3)[3]) == str(i):
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ip parent 1:1 u32 ht 3:' + hexID + ': match ip dst ' + ipv4 + ' flowid ' + classid)
filterHandleCounter += 1
shell('tc filter add dev ' + interface + ' protocol ip parent 1: u32 ht 800: match ip dst 0.0.0.0/0 hashkey mask 0x000000ff at 16 link 3:')
#Recap and log
logging.basicConfig(level=logging.INFO, filename="log", filemode="a+", format="%(asctime)-15s %(levelname)-8s %(message)s")
for device in shapableDevices:
ipAddr = device['identification']['ipAddr']
hostname = device['identification']['hostname']
downloadSpeed = str(device['qos']['downloadMbps'])
uploadSpeed = str(device['qos']['uploadMbps'])
if hostname:
recap = "Applied rate limiting of " + downloadSpeed + " down " + uploadSpeed + " up to device " + hostname
else:
recap = "Applied rate limiting of " + downloadSpeed + " down " + uploadSpeed + " up to device " + ipAddr
logging.info(recap)
print(recap)
totalChanges = str(len(shapableDevices)) + " device rules (" + str(len(shapableDevices)*2) + " filter rules) were applied this round"
logging.info(totalChanges)
print(totalChanges)
#Src
interface = interfaceB
shell('tc filter add dev ' + interface + ' parent 2: protocol ip handle 4: u32 divisor 256')
for i in range (256):
hexID = str(hex(i)).replace('0x','')
for ipv4Filter in ipv4FiltersSrc:
ipv4, parent, classid = ipv4Filter
if '/' in ipv4:
ipv4 = ipv4.split('/')[0]
if (ipv4.split('.', 3)[3]) == str(i):
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ip parent 2:1 u32 ht 4:' + hexID + ': match ip src ' + ipv4 + ' flowid ' + classid)
filterHandleCounter += 1
shell('tc filter add dev ' + interface + ' protocol ip parent 2: u32 ht 800: match ip src 0.0.0.0/0 hashkey mask 0x000000ff at 12 link 4:')
#IPv6 Hash Filters
#Dst
interface = interfaceA
shell('tc filter add dev ' + interface + ' parent 1: handle 5: protocol ipv6 u32 divisor 256')
for ipv6Filter in ipv6FiltersDst:
ipv6, parent, classid = ipv6Filter
withoutCIDR = ipv6.split('/')[0]
third = str(IPv6Address(withoutCIDR).exploded).split(':',5)[3]
usefulPart = third[:2]
hexID = usefulPart
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ipv6 parent 1: u32 ht 5:' + hexID + ': match ip6 dst ' + ipv6 + ' flowid ' + classid)
filterHandleCounter += 1
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' protocol ipv6 parent 1: u32 ht 800:: match ip6 dst ::/0 hashkey mask 0x0000ff00 at 28 link 5:')
filterHandleCounter += 1
#Src
interface = interfaceB
shell('tc filter add dev ' + interface + ' parent 2: handle 6: protocol ipv6 u32 divisor 256')
for ipv6Filter in ipv6FiltersSrc:
ipv6, parent, classid = ipv6Filter
withoutCIDR = ipv6.split('/')[0]
third = str(IPv6Address(withoutCIDR).exploded).split(':',5)[3]
usefulPart = third[:2]
hexID = usefulPart
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ipv6 parent 2: u32 ht 6:' + hexID + ': match ip6 src ' + ipv6 + ' flowid ' + classid)
filterHandleCounter += 1
filterHandle = hex(filterHandleCounter)
shell('tc filter add dev ' + interface + ' protocol ipv6 parent 2: u32 ht 800:: match ip6 src ::/0 hashkey mask 0x0000ff00 at 12 link 6:')
filterHandleCounter += 1
#Done
currentTimeString = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
print("Successful run completed on " + currentTimeString)

27
Shaper.csv Normal file
View File

@ -0,0 +1,27 @@
ID,Hostname,IPv4,IPv6,Download,Upload
,Hostname-1,100.65.0.0,8e95:12ce::/56,100,10
,Hostname-2,100.65.0.1,8e95:12ce:0:100::/56,100,10
,Hostname-3,100.65.0.2,8e95:12ce:0:200::/56,100,10
,Hostname-4,100.65.0.3,8e95:12ce:0:300::/56,100,10
,Hostname-5,100.65.0.4,8e95:12ce:0:400::/56,100,10
,Hostname-6,100.65.0.5,8e95:12ce:0:500::/56,100,10
,Hostname-7,100.65.0.6,8e95:12ce:0:600::/56,100,10
,Hostname-8,100.65.0.7,8e95:12ce:0:700::/56,100,10
,Hostname-9,100.65.0.8,8e95:12ce:0:800::/56,100,10
,Hostname-10,100.65.0.9,8e95:12ce:0:900::/56,100,10
,Hostname-11,100.65.0.10,8e95:12ce:0:a00::/56,100,10
,Hostname-12,100.65.0.11,8e95:12ce:0:b00::/56,100,10
,Hostname-13,100.65.0.12,8e95:12ce:0:c00::/56,100,10
,Hostname-14,100.65.0.13,8e95:12ce:0:d00::/56,100,10
,Hostname-15,100.65.0.14,8e95:12ce:0:e00::/56,100,10
,Hostname-16,100.65.0.15,8e95:12ce:0:f00::/56,100,10
,Hostname-17,100.65.0.16,8e95:12ce:0:1000::/56,100,10
,Hostname-18,100.65.0.17,8e95:12ce:0:1100::/56,100,10
,Hostname-19,100.65.0.18,8e95:12ce:0:1200::/56,100,10
,Hostname-20,100.65.0.19,8e95:12ce:0:1300::/56,100,10
,Hostname-21,100.65.0.20,8e95:12ce:0:1400::/56,100,10
,Hostname-22,100.65.0.21,8e95:12ce:0:1500::/56,100,10
,Hostname-23,100.65.0.22,8e95:12ce:0:1600::/56,100,10
,Hostname-24,100.65.0.23,8e95:12ce:0:1700::/56,100,10
,Hostname-25,100.65.0.24,8e95:12ce:0:1800::/56,100,10
,Hostname-26,100.65.0.25,8e95:12ce:0:1900::/56,100,10
1 ID Hostname IPv4 IPv6 Download Upload
2 Hostname-1 100.65.0.0 8e95:12ce::/56 100 10
3 Hostname-2 100.65.0.1 8e95:12ce:0:100::/56 100 10
4 Hostname-3 100.65.0.2 8e95:12ce:0:200::/56 100 10
5 Hostname-4 100.65.0.3 8e95:12ce:0:300::/56 100 10
6 Hostname-5 100.65.0.4 8e95:12ce:0:400::/56 100 10
7 Hostname-6 100.65.0.5 8e95:12ce:0:500::/56 100 10
8 Hostname-7 100.65.0.6 8e95:12ce:0:600::/56 100 10
9 Hostname-8 100.65.0.7 8e95:12ce:0:700::/56 100 10
10 Hostname-9 100.65.0.8 8e95:12ce:0:800::/56 100 10
11 Hostname-10 100.65.0.9 8e95:12ce:0:900::/56 100 10
12 Hostname-11 100.65.0.10 8e95:12ce:0:a00::/56 100 10
13 Hostname-12 100.65.0.11 8e95:12ce:0:b00::/56 100 10
14 Hostname-13 100.65.0.12 8e95:12ce:0:c00::/56 100 10
15 Hostname-14 100.65.0.13 8e95:12ce:0:d00::/56 100 10
16 Hostname-15 100.65.0.14 8e95:12ce:0:e00::/56 100 10
17 Hostname-16 100.65.0.15 8e95:12ce:0:f00::/56 100 10
18 Hostname-17 100.65.0.16 8e95:12ce:0:1000::/56 100 10
19 Hostname-18 100.65.0.17 8e95:12ce:0:1100::/56 100 10
20 Hostname-19 100.65.0.18 8e95:12ce:0:1200::/56 100 10
21 Hostname-20 100.65.0.19 8e95:12ce:0:1300::/56 100 10
22 Hostname-21 100.65.0.20 8e95:12ce:0:1400::/56 100 10
23 Hostname-22 100.65.0.21 8e95:12ce:0:1500::/56 100 10
24 Hostname-23 100.65.0.22 8e95:12ce:0:1600::/56 100 10
25 Hostname-24 100.65.0.23 8e95:12ce:0:1700::/56 100 10
26 Hostname-25 100.65.0.24 8e95:12ce:0:1800::/56 100 10
27 Hostname-26 100.65.0.25 8e95:12ce:0:1900::/56 100 10

View File

@ -5,58 +5,16 @@
fqOrCAKE = 'fq_codel'
# How many symmetrical Mbps are available to the edge of this network
pipeBandwidthCapacityMbps = 500
pipeBandwidthCapacityMbps = 1000
# Interface connected to edge
interfaceA = 'eth4'
interfaceA = 'eth1'
# Interface connected to core
interfaceB = 'eth5'
interfaceB = 'eth2'
# Allow shell commands. Default is False where commands print to console. MUST BE ENABLED FOR PROGRAM TO FUNCTION
enableActualShellCommands = False
# Add 'sudo' before execution of any shell commands. May be required depending on distribution and environment.
runShellCommandsAsSudo = False
# Import customer QoS rules from UNMS
importFromUNMS = False
# Import customer QoS rules from LibreNMS
importFromLibreNMS = False
# So that new clients are client shaped with something by default, and don't get their traffic de-prioritized,
# you can add specific subnets of hosts to be set to specific speeds.
# These will not override any imports from actual customer data via UNMS or LibreNMS
addTheseSubnets = [
('100.64.0.0/22', 115, 20),
('100.72.4.0/22', 115, 20)
]
# Available on LibreNMS site as https://exampleLibreNMSsite.net/api-access
orgLibreNMSxAuthToken = ''
# Do not include trailing forward slash. For example https://exampleLibreNMSsite.net
libreNMSBaseURL = ''
# Which LibreNMS groups to import. Please create groups in LibreNMS to match these group names such as Plan A
libreNMSDeviceGroups = {
'Plan A': {
'downloadMbps': 25,
'uploadMbps': 3
},
'Plan B': {
'downloadMbps': 50,
'uploadMbps': 5
}
}
# Available under UNMS > Settings > Users
orgUNMSxAuthToken = ''
# Everything before /nms/. Use https:// For example: https://unms.exampleISP.com (no slash after)
unmsBaseURL = ''
# For bridged CPE radios on UNMS, you can exclude matching radio models from rate limiting
deviceModelBlacklistEnabled = False

View File

@ -1,26 +1,3 @@
# 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.71-alpha
#
import time
import schedule
from datetime import date