Skip to content
Snippets Groups Projects
Select Git revision
  • 20dabf626a0604a6bfc44660b0c2dd49e2246ab1
  • v3.3 default protected
  • experimental protected
  • nrb/airmax-test
  • nrb/ro-flash-nanostation-airmax
  • nrb/add-node-whisperer
  • v3.2 protected
  • v3.1 protected
  • nrb-domains
  • v3.0 protected
  • nrb/dns-cache
  • v2.9 protected
  • feature/addMikrotikwAP
  • v2.8 protected
  • v2.5.1 protected
  • v2.7 protected
  • v2.6 protected
  • v2.5 protected
  • v2.4 protected
  • cpe510
  • nrb/gluon-master-cpe510
  • v3.2.1+2024-12-15
  • v3.2+2024-12-04
  • v3.1+2024-07-08
  • v2.9+2023-05-13
  • v2.9+2023-05-12
  • v2.9+2023-05-10
  • v2.8+2023-03-05
  • v2.7+2022-12-03
  • v2.6+2022-09-06
  • v2.5+2022-05-07
  • v2.5+2022-05-05
  • v2.4+2022-02-26
  • v2.3+2021-06-03
  • v2.3+2021-04-30
  • v2.2+2021-04-16
  • v2.2+2020-04-16
  • v2.1+2020-12-11
  • v2.1+2020-11-17
  • v2.0+2020-09-26
  • v2.0+2020-06-28
41 results

image-customization.lua

Blame
  • update_checker.py 3.97 KiB
    #!/usr/bin/python3
    import json
    import netaddr
    import gzip
    import re
    import os
    import sys
    import pprint
    import requests
    import argparse
    import datetime
    MAC_URL = 'http://macvendors.co/api/%s'
    
    ap = argparse.ArgumentParser()
    ap.add_argument("--raw", type=argparse.FileType("r", encoding="utf-8"), required=True)
    args = ap.parse_args()
    
    def getHardwareModelFromEntry(d):
        try: 
            hardware_model = d["nodeinfo"]["hardware"]["model"]
        except KeyError:
            hardware_model = "UNKNOWN"
    
        return hardware_model
    
    def ipv62mac(ipv6):
        # remove subnet info if given
        subnetIndex = ipv6.find("/")
        if subnetIndex != -1:
            ipv6 = ipv6[:subnetIndex]
    
        ipv6Parts = ipv6.split(":")
        macParts = []
        for ipv6Part in ipv6Parts[-4:]:
            while len(ipv6Part) < 4:
                ipv6Part = "0" + ipv6Part
            macParts.append(ipv6Part[:2])
            macParts.append(ipv6Part[-2:])
    
        # modify parts to match MAC value
        macParts[0] = "%02x" % (int(macParts[0], 16) ^ 2)
        del macParts[4]
        del macParts[3]
    
        return ":".join(macParts)
    
    class LogRecordParseError(Exception):
        def __init__(self, record_line):
            self.record_line = record_line
    
    class LogRecord:
        def __init__(self,record):
            record = record.replace("%2B","+")
            regex = r'(fd21.*) - - \[(.*) "GET /gluon/(.*)/sysupgrade/gluon-ffs-([0-9]\.[0-9]\+[0-9]+-[0-9]+-[0-9]+-g\.[0-9a-z]+-s\.[0-9a-z]+)-(.*)\ HTTP/1.1" ([0-9]+) [0-9]+ "-" "(.*)"'
            result = re.search(regex,record)
            try:
                groups = result.groups()
            except:
                raise LogRecordParseError(record)
            self.ipv6 = groups[0]
            self.date = groups[1]
            self.branch = groups[2]
            self.release = groups[3]
            self.model = groups[4]
            self.status = groups[5]
            self.agent = groups[6]
            self.segment = int(self.ipv6.split(":")[2][2:])
    
    try:
        allFirmwareDownloads = json.load(open("firmwareDownloads.json","r"))
    except:
        allFirmwareDownloads = []
    
    access = ""
    
    try:
        #for i in range(2,15):
        #   access += gzip.open("/var/log/nginx/access.log.%i.gz"%(i),"rt").read()
        access += open("/var/log/nginx/access.log.1").read()
        access += open("/var/log/nginx/access.log").read()
    
    except:
        print("not using /var/log/nginx/access.log")
    try:
        access += open("access.log").read()
    except:
        pass
    
    allDownloads = access.strip().split("\n")
    allNewFirmwareDownloads = [l for l in allDownloads if l.startswith("fd21:") and "sysupgrade" in l and "manifest" not in l]
    
    for f in allNewFirmwareDownloads:
        if f not in allFirmwareDownloads:
            allFirmwareDownloads.append(f)
    
    json.dump(allFirmwareDownloads,open("firmwareDownloads.json","w"),sort_keys=True, indent=4, separators=(',', ': '))
    
    
    data = json.load(args.raw)
    
    for download in allFirmwareDownloads:
        try:
            r = LogRecord(download)
        except LogRecordParseError as e:
            print("error parsing line, skipping: {}".format(e.record_line))
            continue
    
        mac = ipv62mac(r.ipv6)
    
        nodes_with_mac = [node for node in data["nodes"] if node["nodeinfo"]["network"]["mac"] == mac]
    
        if len(nodes_with_mac) == 1:
            d = nodes_with_mac[0]
            currentRelease = d["nodeinfo"]["software"]["firmware"]["release"]
            status = d["online"]
            hostname = d["nodeinfo"]["hostname"]
            hardware_model = getHardwareModelFromEntry(d)
            if currentRelease < r.release:
                print("%s (%s) %s -> %s Segment %i %s status %s @ %s" % (mac, hostname, currentRelease, r.release, r.segment, hardware_model, status, r.date))
        else:
            #request = requests.get(MAC_URL % mac)
            #pprint.pprint(request.json())
            # raw.json only contains data from 14 days - do not print message if we encounter older log entries
            download_ts = datetime.datetime.strptime(r.date, "%d/%b/%Y:%H:%M:%S %z]")
            if download_ts - datetime.datetime.now(tz=datetime.timezone.utc) > datetime.timedelta(days=14):
                print("%s %s with agent %s seems not to be a node @ %s"%(r.ipv6,mac,r.agent,r.date))