multi login support, tested MC889

main
"Riku" 2024-07-11 12:28:14 +03:00
parent 936dcde75c
commit 57503b356c
4 changed files with 28 additions and 30 deletions

View File

@ -3,4 +3,4 @@ FROM python:3.11
RUN pip install requests urllib3
ADD zte_exporter.py .
CMD python3 zte_exporter.py $PORT $IP $USERNAME $PASSWORD
CMD python3 zte_exporter.py $PORT $IP $USERNAME $PASSWORD $LOGIN

View File

@ -9,3 +9,4 @@ services:
- IP=192.168.8.1
- USERNAME=admin
- PASSWORD=1234
- LOGIN=single

View File

@ -2,13 +2,15 @@
## Getting started
One can just run the provided python script by `python3 zte_exporter <port> <router ip> <admin username> <admin password>`
One can just run the provided python script by `python3 zte_exporter.py <port> <router ip> <admin username> <admin password> <login method>`
A docker file is provided to compile this and example compose.yml to use in compose tools. To use with docker run, just create .env with the correct values. dockerhub vvkvvk/zte-exporter has the latest version of this available.
Login method depends on the used router, f.e MC7010 uses single login and MC889A has multi. You can tell by if the login page asks for username (multi) or if it's just password (single). On single login the username variable is not used at all so it can be set whatever you fancy.
A docker file is provided to compile this and example compose.yml to use in compose tools. To use with docker run, just create .env with the correct values. dockerhub vvkvvk/zte-exporter has the latest version of this available. A compose.yml file is provided as example.
## Tested devices
Probably works with other ZTE models, only tested with ZTE MC7010. A simple Grafana dashboard included with the grafana.json.
Probably works with other ZTE models, only tested with ZTE MC7010 and MC889A. A simple Grafana dashboard included with the grafana.json.
## Thanks

View File

@ -15,8 +15,9 @@ import argparse
parser = argparse.ArgumentParser("ZTE simple exporter")
parser.add_argument("port", help="Serve metrics on what port", type=int)
parser.add_argument("ip", help="Router ip address")
parser.add_argument("username", help="Router username")
parser.add_argument("username", help="Router username", default="admin")
parser.add_argument("password", help="Router password")
parser.add_argument("--login", help="Login method (multi, single)", default="single")
args = parser.parse_args()
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
@ -25,7 +26,8 @@ s = requests.Session()
class zteRouter:
def __init__(self, ip, username, password):
def __init__(self, ip, username, password, login):
self.login = login
self.ip = ip
self.protocol = "http" # default to http
self.username = username
@ -50,44 +52,37 @@ class zteRouter:
def hash(self, str):
return hashlib.sha256(str.encode()).hexdigest()
def getVersion(self):
header = {"Referer": self.referer}
payload = "isTest=false&cmd=wa_inner_version"
r = s.get(self.referer + f"goform/goform_get_cmd_process?{payload}", headers=header, data=payload, verify=False)
return r.json()["wa_inner_version"]
def get_LD(self):
header = {"Referer": self.referer}
payload = "isTest=false&cmd=LD"
r = s.get(self.referer + f"goform/goform_get_cmd_process?{payload}", headers=header, data=payload, verify=False)
r = s.get(self.referer + f"goform/goform_get_cmd_process?{payload}&_=", headers=header, data=payload, verify=False)
return r.json()["LD"].upper()
def getCookie(self, username, password, LD):
def getCookie(self, username, password, LD, login):
header = {"Referer": self.referer}
hashPassword = self.hash(password).upper()
ztePass = self.hash(hashPassword + LD).upper()
old_login = self.getVersion()
if login == "multi":
payload = {
'isTest': 'false',
'goformId': 'LOGIN' if username is not None and old_login in 'MC801' or 'MC7010' else 'LOGIN_MULTI_USER',
'password': ztePass
'goformId': 'LOGIN_MULTI_USER',
'password': ztePass,
'user': username
}
else:
payload = {
'isTest': 'false',
'goformId': 'LOGIN',
'password': ztePass,
}
if username is not None and username != "":
payload['username'] = username
r = s.post(self.referer + "goform/goform_set_cmd_process", headers=header, data=payload, verify=False)
return "stok=" + r.cookies["stok"].strip('\"')
def get_RD(self):
header = {"Referer": self.referer}
payload = "isTest=false&cmd=RD"
r = s.post(self.referer + "goform/goform_get_cmd_process", headers=header, data=payload, verify=False)
return r.json()["RD"]
def zteinfo(self):
ip = self.ip
cookie = self.getCookie(username=self.username, password=self.password, LD=self.get_LD())
cookie = self.getCookie(username=self.username, password=self.password, LD=self.get_LD(), login=self.login)
cmd_url = f"{self.protocol}://{self.ip}/goform/goform_get_cmd_process?multi_data=1&isTest=false&cmd=wa_inner_version%2Clte_rssi%2CZ5g_rssi%2Clte_rsrp%2CZ5g_rsrp%2Clte_rsrq%2CZ5g_rsrq%2Clte_snr%2CZ5g_SINR%2Csignalbar%2Ccell_id%2Cnr5g_action_band%2Ccell_id%2Cnetwork_provider%2Cmonthly_tx_bytes%2Cmonthly_rx_bytes%2Crealtime_tx_bytes%2Crealtime_rx_bytes%2Crealtime_tx_thrpt%2Crealtime_rx_thrpt%2Cwan_ipaddr%2Cwan_apn"
cookie_pass = cookie
@ -100,7 +95,7 @@ class zteRouter:
response = s.get(cmd_url, headers=headers, verify=False)
return response.text
zteInstance = zteRouter(args.ip, args.username, args.password)
zteInstance = zteRouter(args.ip, args.username, args.password, args.login)
serverPort = args.port
class serveInfos(BaseHTTPRequestHandler):