forked from acouzens/open5gs
Some cleanup for the db migration script (#956)
This commit is contained in:
parent
fc27f7499b
commit
72374e439a
|
@ -1,4 +1,3 @@
|
||||||
import mongo
|
|
||||||
import pymongo
|
import pymongo
|
||||||
import random
|
import random
|
||||||
import bson
|
import bson
|
||||||
|
@ -8,7 +7,6 @@ class Open5GS:
|
||||||
self.server = server
|
self.server = server
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
|
||||||
def GetSubscribers(self):
|
def GetSubscribers(self):
|
||||||
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
||||||
mydb = myclient["open5gs"]
|
mydb = myclient["open5gs"]
|
||||||
|
@ -30,14 +28,12 @@ class Open5GS:
|
||||||
for x in mydoc:
|
for x in mydoc:
|
||||||
print(x)
|
print(x)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def AddSubscriber(self, sub_data):
|
def AddSubscriber(self, sub_data):
|
||||||
|
|
||||||
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
||||||
mydb = myclient["open5gs"]
|
mydb = myclient["open5gs"]
|
||||||
mycol = mydb["subscribers"]
|
mycol = mydb["subscribers"]
|
||||||
|
|
||||||
x = mycol.insert_one(sub_data)
|
x = mycol.insert_one(sub_data)
|
||||||
print("Added subscriber with Inserted ID : " + str(x.inserted_id))
|
print("Added subscriber with Inserted ID : " + str(x.inserted_id))
|
||||||
return x.inserted_id
|
return x.inserted_id
|
||||||
|
@ -53,7 +49,6 @@ class Open5GS:
|
||||||
print(x)
|
print(x)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def DeleteSubscriber(self, imsi):
|
def DeleteSubscriber(self, imsi):
|
||||||
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
myclient = pymongo.MongoClient("mongodb://" + str(self.server) + ":" + str(self.port) + "/")
|
||||||
mydb = myclient["open5gs"]
|
mydb = myclient["open5gs"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## Open5GS Python Library
|
## Open5GS Python Library
|
||||||
|
|
||||||
Basic Python library to interface with MongoDB subscriber DB in Open5GS HSS / PCRF. Requires Python 3+, mongo, pymongo and bson. (All available through PIP)
|
Basic Python library to interface with MongoDB subscriber DB in Open5GS HSS / PCRF. Requires Python 3+, pymongo and bson. (All available through PIP)
|
||||||
|
|
||||||
If you are planning to run this on a different machine other than localhost (the machine hosting the MongoDB service) you will need to enable remote access to MongoDB by binding it's IP to 0.0.0.0:
|
If you are planning to run this on a different machine other than localhost (the machine hosting the MongoDB service) you will need to enable remote access to MongoDB by binding it's IP to 0.0.0.0:
|
||||||
|
|
||||||
|
|
|
@ -3,66 +3,101 @@
|
||||||
#Additional functionlality like PCC rules, static assignment etc, not tested. If it's not listed below it's probably not migrated by this script.
|
#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
|
#Written by @nickvsnetworking 30/03/2021
|
||||||
|
|
||||||
import json
|
import copy
|
||||||
import sys
|
|
||||||
import random, string
|
|
||||||
import mongo
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
|
||||||
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
|
|
||||||
mydb = myclient["open5gs"]
|
|
||||||
mycol = mydb["subscribers"]
|
|
||||||
subs_list = []
|
|
||||||
for x in mycol.find():
|
|
||||||
if 'schema_version' not in x:
|
|
||||||
print("Subscriber record " + str(x['imsi']) + " needs updating")
|
|
||||||
old_template_json = x
|
|
||||||
print(old_template_json)
|
|
||||||
#Set AMBR Values to new format (Old format is in bits per second)
|
|
||||||
try:
|
|
||||||
uplink = old_template_json['ambr']['uplink']
|
|
||||||
old_template_json['ambr']['uplink'] = {}
|
|
||||||
old_template_json['ambr']['uplink']['value'] = uplink
|
|
||||||
old_template_json['ambr']['uplink']['unit'] = 0
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
print("Failed to set Uplink AMBR values")
|
|
||||||
|
|
||||||
try:
|
def migrate_all_subscribers(mycol):
|
||||||
downlink = old_template_json['ambr']['downlink']
|
"""Migrates all subscribers in the mycol collection from schema version 0 to version 1
|
||||||
old_template_json['ambr']['downlink'] = {}
|
"""
|
||||||
old_template_json['ambr']['downlink']['value'] = downlink
|
for x in mycol.find():
|
||||||
old_template_json['ambr']['downlink']['unit'] = 0
|
if 'schema_version' not in x:
|
||||||
except Exception as e:
|
imsi = x['imsi']
|
||||||
print(e)
|
print("Subscriber record " + str(imsi) + " needs updating")
|
||||||
print("Failed to set Downlink AMBR values")
|
|
||||||
|
|
||||||
#Propogate APN / DDN Slice Details
|
print("Current value:", x)
|
||||||
old_template_json['slice'] = []
|
new_subscriber = create_v1_from_v0(x)
|
||||||
old_template_json['slice'].append({"sst": 1, "default_indicator" : True, "session" : []})
|
print("Migrated value:", new_subscriber)
|
||||||
|
|
||||||
i = 0
|
|
||||||
while i < len(old_template_json['pdn']):
|
|
||||||
ddn_dict = {}
|
|
||||||
ddn_dict['name'] = old_template_json['pdn'][i]['apn']
|
|
||||||
ddn_dict['type'] = old_template_json['pdn'][i]['type']
|
|
||||||
ddn_dict['pcc_rule'] = old_template_json['pdn'][i]['pcc_rule']
|
|
||||||
ddn_dict['qos'] = old_template_json['pdn'][i]['qos']
|
|
||||||
ddn_dict['qos']['index'] = old_template_json['pdn'][i]['qos']['qci']
|
|
||||||
ddn_dict['qos']['arp'] = old_template_json['pdn'][i]['qos']['arp']
|
|
||||||
ddn_dict['ambr'] = {"uplink": {"value": old_template_json['pdn'][i]['ambr']['uplink'], "unit": 0}, "downlink": {"value": old_template_json['pdn'][i]['ambr']['downlink'], "unit": 0}}
|
|
||||||
i += 1
|
|
||||||
old_template_json['slice'][0]['session'].append(ddn_dict)
|
|
||||||
|
|
||||||
#Remove old PDN info
|
|
||||||
#del old_template_json['pdn']
|
|
||||||
|
|
||||||
#Add "schema_version" feild
|
#Write back to MongoDB
|
||||||
old_template_json['schema_version'] = 1
|
myquery = { "imsi": str(imsi) }
|
||||||
|
newvalues = {
|
||||||
|
"$set": new_subscriber,
|
||||||
|
"$unset": {"pdn": 1}
|
||||||
|
}
|
||||||
|
mycol.update_one(myquery, newvalues)
|
||||||
|
print("Updated OK")
|
||||||
|
|
||||||
#Write back to MongoDB
|
|
||||||
myquery = { "imsi": str(old_template_json['imsi'])}
|
|
||||||
newvalues = { "$set": old_template_json }
|
|
||||||
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 bits per second)
|
||||||
|
new_sub['ambr']['uplink'] = {}
|
||||||
|
new_sub['ambr']['uplink']['value'] = old_sub['ambr']['uplink']
|
||||||
|
new_sub['ambr']['uplink']['unit'] = 0
|
||||||
|
|
||||||
|
new_sub['ambr']['downlink'] = {}
|
||||||
|
new_sub['ambr']['downlink']['value'] = old_sub['ambr']['downlink']
|
||||||
|
new_sub['ambr']['downlink']['unit'] = 0
|
||||||
|
|
||||||
|
#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']
|
||||||
|
session['type'] = pdn['type']
|
||||||
|
session['ambr'] = {
|
||||||
|
"uplink": {
|
||||||
|
"value": pdn['ambr']['uplink'],
|
||||||
|
"unit": 0
|
||||||
|
},
|
||||||
|
"downlink": {
|
||||||
|
"value": pdn['ambr']['downlink'],
|
||||||
|
"unit": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"])
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
import unittest
|
||||||
|
import pymongo
|
||||||
|
|
||||||
|
import SchemaUpdater
|
||||||
|
|
||||||
|
class TestSchemaUpdater(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.legacy_sub = {
|
||||||
|
'imsi': '999990000000001',
|
||||||
|
'access_restriction_data': 32,
|
||||||
|
'ambr': {
|
||||||
|
'downlink': 1024000,
|
||||||
|
'uplink': 1024000
|
||||||
|
},
|
||||||
|
'network_access_mode': 2,
|
||||||
|
'pdn': [
|
||||||
|
{
|
||||||
|
'apn': 'internet',
|
||||||
|
'pcc_rule': [],
|
||||||
|
'ambr': {
|
||||||
|
'downlink': 1024000,
|
||||||
|
'uplink': 1024000
|
||||||
|
},
|
||||||
|
'qos': {
|
||||||
|
'qci': 9,
|
||||||
|
'arp': {
|
||||||
|
'priority_level': 8,
|
||||||
|
'pre_emption_vulnerability': 1,
|
||||||
|
'pre_emption_capability': 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'type': 0,
|
||||||
|
'ue': {
|
||||||
|
'addr': '10.45.1.1',
|
||||||
|
'addr6': 'dead:beef::1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'security': {
|
||||||
|
'k': 'iamatransparentsecretkeystringk',
|
||||||
|
'amf': '8000',
|
||||||
|
'op': None,
|
||||||
|
'opc': 'iamatransparentsecretopcstring'
|
||||||
|
},
|
||||||
|
'subscribed_rau_tau_timer': 12,
|
||||||
|
'subscriber_status': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_top_level_migration(self):
|
||||||
|
new_sub = SchemaUpdater.create_v1_from_v0(self.legacy_sub)
|
||||||
|
self.assertEqual(new_sub["imsi"], self.legacy_sub["imsi"])
|
||||||
|
self.assertEqual(new_sub["subscriber_status"], self.legacy_sub["subscriber_status"])
|
||||||
|
self.assertEqual(new_sub["subscribed_rau_tau_timer"], self.legacy_sub["subscribed_rau_tau_timer"])
|
||||||
|
self.assertEqual(new_sub["network_access_mode"], self.legacy_sub["network_access_mode"])
|
||||||
|
self.assertEqual(new_sub["access_restriction_data"], self.legacy_sub["access_restriction_data"])
|
||||||
|
|
||||||
|
def test_ambr_migration(self):
|
||||||
|
new_sub = SchemaUpdater.create_v1_from_v0(self.legacy_sub)
|
||||||
|
self.assertEqual(
|
||||||
|
new_sub["ambr"]["uplink"]["value"] * (1000 ** new_sub["ambr"]["uplink"]["unit"]),
|
||||||
|
self.legacy_sub["ambr"]["uplink"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
new_sub["ambr"]["downlink"]["value"] * (1000 ** new_sub["ambr"]["downlink"]["unit"]),
|
||||||
|
self.legacy_sub["ambr"]["downlink"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_pdn_migration(self):
|
||||||
|
new_sub = SchemaUpdater.create_v1_from_v0(self.legacy_sub)
|
||||||
|
self.assertEqual(len(new_sub["slice"]), 1)
|
||||||
|
self.assertEqual(len(new_sub["slice"][0]["session"]), len(self.legacy_sub["pdn"]))
|
||||||
|
|
||||||
|
session = new_sub["slice"][0]["session"][0]
|
||||||
|
self.assertEqual(
|
||||||
|
session["ambr"]["uplink"]["value"] * (1000 ** session["ambr"]["uplink"]["unit"]),
|
||||||
|
self.legacy_sub["pdn"][0]["ambr"]["uplink"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
session["ambr"]["downlink"]["value"] * (1000 ** session["ambr"]["downlink"]["unit"]),
|
||||||
|
self.legacy_sub["pdn"][0]["ambr"]["downlink"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
session["ue"]["addr"],
|
||||||
|
self.legacy_sub["pdn"][0]["ue"]["addr"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
session["ue"]["addr6"],
|
||||||
|
self.legacy_sub["pdn"][0]["ue"]["addr6"]
|
||||||
|
)
|
Loading…
Reference in New Issue