@@ -35,58 +35,87 @@ def run(self):
3535 laces_df = laces_df [laces_df [f'GCD_ICMPv{ self .ip_version } ' ] > 1 ]
3636
3737 anycast_prefixes = set ()
38+ geo_prefixes = set ()
3839 points = set ()
40+ countries = set ()
3941 located_in_links = list ()
42+ country_links = list ()
4043
4144 # Iterate over rows creating anycast prefixes and points.
4245 for idx , row in laces_df .iterrows ():
46+ ref_data = row .to_dict ()
4347 try :
44- ref_data = row .to_dict ()
4548 prefix = ip_network (ref_data .pop ('prefix' )).compressed
46- locations = ref_data .pop ('locations' )
47- anycast_prefixes .add (prefix )
48-
49- # Create a point and LOCATED_IN link for each location.
50- for location in locations :
51- lat = location .pop ('lat' )
52- lon = location .pop ('lon' )
53- point = WGS84Point ((lon , lat ))
54- points .add (point )
55-
56- # Include location metadata in link properties, exclude None values.
57- ref_data .update ({k : v for k , v in location .items () if v })
58-
59- located_in_links .append ({
49+ except ValueError as e :
50+ logging .warning (f'Ignoring malformed prefix: "{ row .prefix } ": { e } ' )
51+ continue
52+ locations = ref_data .pop ('locations' )
53+ anycast_prefixes .add (prefix )
54+
55+ # Create a point and LOCATED_IN link for each location.
56+ if locations .any ():
57+ geo_prefixes .add (prefix )
58+ for location in locations :
59+ lat = location .pop ('lat' )
60+ lon = location .pop ('lon' )
61+ point = WGS84Point ((lon , lat ))
62+ points .add (point )
63+
64+ # Include location metadata in link properties, exclude None values.
65+ ref_data .update ({k : v for k , v in location .items () if v })
66+
67+ located_in_links .append ({
68+ 'src_id' : prefix ,
69+ 'dst_id' : point ,
70+ 'props' : [
71+ self .reference ,
72+ dict (ref_data ),
73+ ],
74+ })
75+
76+ # Some entries only have WGS84 coordinates, but no country mapping.
77+ if location ['country_code' ]:
78+ country = location ['country_code' ]
79+ countries .add (country )
80+ country_links .append ({
6081 'src_id' : prefix ,
61- 'dst_id' : point ,
82+ 'dst_id' : country ,
6283 'props' : [
6384 self .reference ,
6485 dict (ref_data ),
6586 ],
6687 })
6788
68- except ValueError as e :
69- logging .warning (f'Ignoring malformed prefix: "{ row .prefix } ": { e } ' )
70- continue
71-
7289 # Get all IYP prefix IDs for our anycast prefixes and points.
7390 anycast_prefix_id = self .iyp .batch_get_nodes_by_single_prop (
7491 'AnycastPrefix' ,
7592 'prefix' ,
7693 anycast_prefixes ,
7794 all = False
7895 )
96+ geo_prefix_id = self .iyp .batch_get_nodes_by_single_prop (
97+ 'GeoPrefix' ,
98+ 'prefix' ,
99+ anycast_prefixes ,
100+ all = False
101+ )
79102 point_id = self .iyp .batch_get_nodes_by_single_prop ('Point' , 'position' , points , all = False )
103+ country_id = self .iyp .batch_get_nodes_by_single_prop ('Country' , 'country_code' , countries , all = False )
80104
81- # Add Prefix labels to AnycastPrefix nodes.
105+ # Add Prefix labels to AnycastPrefix and GeoPrefix nodes.
82106 self .iyp .batch_add_node_label (list (anycast_prefix_id .values ()), 'Prefix' )
107+ self .iyp .batch_add_node_label (list (geo_prefix_id .values ()), 'Prefix' )
83108
84109 # Replace links values with node ids.
85110 for link in located_in_links :
86- link ['src_id' ] = anycast_prefix_id [link ['src_id' ]]
111+ link ['src_id' ] = geo_prefix_id [link ['src_id' ]]
87112 link ['dst_id' ] = point_id [link ['dst_id' ]]
113+ for link in country_links :
114+ link ['src_id' ] = geo_prefix_id [link ['src_id' ]]
115+ link ['dst_id' ] = country_id [link ['dst_id' ]]
88116
89117 self .iyp .batch_add_links ('LOCATED_IN' , located_in_links )
118+ self .iyp .batch_add_links ('COUNTRY' , country_links )
90119
91120 def unit_test (self ):
92- return super ().unit_test (['LOCATED_IN' ])
121+ return super ().unit_test (['LOCATED_IN' , 'COUNTRY' ])
0 commit comments