open5gs/misc/db/python/SchemaUpdater.py

110 lines
3.3 KiB
Python

#Open5GS MongoDB Schema Update Script
#Updates existing subscribers configured prior to the database change to the new format to work with more recent version of Open5GS
#Additional functionlality like PCC rules, static assignment etc, not tested. If it's not listed below it's probably not migrated by this script.
#Written by @nickvsnetworking 30/03/2021
import copy
import pymongo
def migrate_all_subscribers(mycol):
"""Migrates all subscribers in the mycol collection from schema version 0 to version 1
"""
for x in mycol.find():
if 'schema_version' not in x:
imsi = x['imsi']
print("Subscriber record " + str(imsi) + " needs updating")
print("Current value:", x)
new_subscriber = create_v1_from_v0(x)
print("Migrated value:", new_subscriber)
#Write back to MongoDB
myquery = { "imsi": str(imsi) }
newvalues = {
"$set": new_subscriber,
"$unset": {"pdn": 1}
}
mycol.update_one(myquery, newvalues)
print("Updated OK")
def create_v1_from_v0(old_sub):
"""Create a v1 subscriber from an existing v0 subscriber
"""
# Make a copy to avoid mutating the existing subscriber object so it can be
# re-used for other parts of the migration.
new_sub = copy.deepcopy(old_sub)
# Remove old PDN info
del new_sub['pdn']
# Set AMBR Values to new format (Old format is in kbps per second)
new_sub['ambr']['uplink'] = {}
new_sub['ambr']['uplink']['value'] = old_sub['ambr']['uplink']
new_sub['ambr']['uplink']['unit'] = 1
new_sub['ambr']['downlink'] = {}
new_sub['ambr']['downlink']['value'] = old_sub['ambr']['downlink']
new_sub['ambr']['downlink']['unit'] = 1
#Propogate APN / DDN Slice Details
new_sub['slice'] = []
new_sub['slice'].append({"sst": 1, "default_indicator" : True, "session" : []})
for pdn_entry in old_sub["pdn"]:
session = _create_session_from_pdn(pdn_entry)
new_sub['slice'][0]['session'].append(session)
#Add "schema_version" feild
new_sub['schema_version'] = 1
return new_sub
def _create_session_from_pdn(pdn):
"""Builds a new session object from an existing PDN"""
session = {}
session['name'] = pdn['apn']
if pdn['type'] in {1, 2, 3}:
session['type'] = pdn['type']
else:
# Default to IPv4 for old networks being upgraded with an invalid type
session['type'] = 1
session['ambr'] = {
"uplink": {
"value": pdn['ambr']['uplink'],
"unit": 1
},
"downlink": {
"value": pdn['ambr']['downlink'],
"unit": 1
}
}
if "qos" in pdn:
session["qos"] = {
"index": pdn["qos"]["qci"],
"arp": pdn["qos"]["arp"]
}
if "smf" in pdn:
session["smf"] = pdn["smf"]
if "ue" in pdn:
session["ue"] = pdn["ue"]
if ("pcc_rule" in pdn) and (len(pdn['pcc_rule']) != 0):
raise NotImplementedError("PCC Rule Migration Not Implemented")
else:
session["pcc_rule"] = []
return session
if __name__ == "__main__":
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["open5gs"]
migrate_all_subscribers(mycol=mydb["subscribers"])