@@ -71,6 +71,9 @@ class JsonSchema
7171 self ::EUROIX_JSON_VERSION_1_0 ,
7272 ];
7373
74+ // the data to export
75+ private array $ output = [];
76+
7477 /**
7578 * Get the JSON schema (for a given version or for the latest version)
7679 *
@@ -90,26 +93,26 @@ public function get( ?string $version = null, bool $asArray = false, bool $detai
9093 }
9194
9295 /** @psalm-suppress UndefinedConstant */
93- $ output = [
96+ $ this -> output = [
9497 'version ' => $ version ,
9598 'generator ' => 'IXP Manager v ' . APPLICATION_VERSION ,
9699 ];
97100
98101 // normalise times to UTC for exports
99102 date_default_timezone_set ('UTC ' );
100- $ output ['timestamp ' ] = now ()->toIso8601ZuluString ();
103+ $ this -> output ['timestamp ' ] = now ()->toIso8601ZuluString ();
101104
102- $ output [ ' ixp_list ' ] = $ this ->getIXPInfo ( $ version );
103- $ output ['member_list ' ] = $ this ->getMemberInfo ( $ version , $ detailed , $ tags );
105+ $ infrasIncluded = $ this ->getIXPInfo ( $ version );
106+ $ this -> output ['member_list ' ] = $ this ->getMemberInfo ( $ version , $ detailed , $ tags, $ infrasIncluded );
104107
105108 // apply filters as some IXs don't want to export all details
106- $ output = $ this ->filter ($ output );
109+ $ this -> output = $ this ->filter ($ this -> output );
107110
108111 if ( $ asArray ) {
109- return $ output ;
112+ return $ this -> output ;
110113 }
111114
112- return json_encode ( $ output , JSON_PRETTY_PRINT )."\n" ;
115+ return json_encode ( $ this -> output , JSON_PRETTY_PRINT )."\n" ;
113116 }
114117
115118 /**
@@ -132,18 +135,19 @@ public function sanitiseVersion( string $version ): string
132135 * Collate the IXP specific information for the JSON schema export
133136 *
134137 * @param string $version The version to collate the detail for
135- *
136- * @return (|(array|mixed|value-of<TArray>)[]|int|null|string)[][]
137- *
138138 * @throws
139- *
140- * @psalm-return list{0?: array{shortname: null|string, name: , country: |string, url: , peeringdb_id?: int, ixf_id?: int, ixp_id: int, support_email: , support_phone: , support_contact_hours: , emergency_email: , emergency_phone: , emergency_contact_hours: , billing_contact_hours: , billing_email: , billing_phone: , peering_policy_list: non-empty-list<value-of<never>>, vlan: array<int<0, max>, array<string, mixed>>, switch: array},...}
141139 */
142140 private function getIXPInfo ( string $ version ): array
143141 {
144142 $ ixpinfo = [];
143+ $ infrasIncluded = [];
145144
146145 foreach ( Infrastructure::with ( ['switchers.cabinet.location ' ] )->get () as $ infra ) {
146+
147+ if ( $ infra ->exclude_from_ixf_export ) {
148+ continue ;
149+ }
150+
147151 $ i = [];
148152 $ i ['shortname ' ] = $ infra ->name ;
149153 $ i ['name ' ] = config ('identity.legalname ' );
@@ -182,6 +186,8 @@ private function getIXPInfo( string $version ): array
182186 }
183187 }
184188
189+ $ infrasIncluded [] = $ infra ->id ;
190+
185191 $ i ['ixp_id ' ] = $ infra ->id ; // referenced in member's connections section
186192
187193 $ i ['support_email ' ] = config ('identity.support_email ' );
@@ -237,8 +243,10 @@ private function getIXPInfo( string $version ): array
237243
238244 $ ixpinfo [] = $ i ;
239245 }
240-
241- return $ ixpinfo ;
246+
247+ $ this ->output ['ixp_list ' ] = $ ixpinfo ;
248+
249+ return $ infrasIncluded ;
242250 }
243251
244252 /**
@@ -288,16 +296,8 @@ private function getSwitchInfo( string $version, Infrastructure $infra ): array
288296
289297 /**
290298 * Collate the IXP's member information for the JSON schema export
291- *
292- * @param string $version The version to collate the detail for
293- * @param bool $detailed
294- * @param bool $tags
295- *
296- * @return ((((((stdClass|string)[]|bool|int|mixed|string)[]|int|null)[][]|mixed|string)[]|bool|int|null|string)[]|int|null|string)[][]
297- *
298- * @psalm-return array<int<0, max>, array{asnum: int|null, member_since: string, url: null|string, name: null|string, peering_policy: null|string, member_type: string, contact_email?: list{null|string}, contact_phone?: list{null|string}, peering_policy_url?: null|string, contact_hours?: string, ixp_manager?: array{tags: array<string, string>, in_manrs: bool, is_reseller: bool, is_resold: bool, resold_via_asn?: int|null}, connection_list: list<array{if_list: list{0?: array{if_phys_speed?: int|null, if_speed: int, switch_id: int|null}, ...<array{if_phys_speed?: int|null, if_speed: int, switch_id: int|null}>}, ixp_id: mixed, state: 'active', vlan_list: list{non-empty-array<non-empty-literal-string, array{address: mixed, as_macro?: string, mac_addresses?: list{0?: string, ...<string>}, max_prefix?: int, routeserver: bool, service_type?: list{'ixroutecollector'|'ixrouteserver', ...<'ixroutecollector'|'ixrouteserver'>}, services?: list{stdClass, ...<stdClass>}}|int|null>, ...<non-empty-array<non-empty-literal-string, array{address: mixed, as_macro?: string, mac_addresses?: list{0?: string, ...<string>}, max_prefix?: int, routeserver: bool, service_type?: list{'ixroutecollector'|'ixrouteserver', ...<'ixroutecollector'|'ixrouteserver'>}, services?: list{stdClass, ...<stdClass>}}|int|null>>}}>}>
299299 */
300- private function getMemberInfo ( string $ version , bool $ detailed , bool $ tags ): array
300+ private function getMemberInfo ( string $ version , bool $ detailed , bool $ tags, array $ infrasIncluded ): array
301301 {
302302 $ memberinfo = [];
303303
@@ -374,6 +374,9 @@ private function getMemberInfo( string $version, bool $detailed, bool $tags ): a
374374 }
375375 }
376376 }
377+
378+ // ensure we have at least one interface on an included infrastructure
379+ $ atLeastOneInfraIsConnected = false ;
377380
378381 foreach ( $ c ->virtualInterfaces as $ vi ) {
379382 $ iflist = [];
@@ -386,6 +389,15 @@ private function getMemberInfo( string $version, bool $detailed, bool $tags ): a
386389 continue ;
387390 }
388391
392+ // is this an infrastructure we are including?
393+ try {
394+ if ( !in_array ( $ pi ->switchPort ->switcher ->infrastructure , $ infrasIncluded ) ) {
395+ continue ;
396+ }
397+ } catch ( \Exception $ e ) {
398+ dd ($ pi );
399+ }
400+
389401 $ atLeastOnePiIsPeering = true ;
390402
391403 if ( $ pi ->statusConnected () ) {
@@ -407,7 +419,9 @@ private function getMemberInfo( string $version, bool $detailed, bool $tags ): a
407419 if ( !$ atLeastOnePiIsPeering || !$ atLeastOnePiIsConnected ) {
408420 continue ;
409421 }
410-
422+
423+ $ atLeastOneInfraIsConnected = true ;
424+
411425 $ vlanentries = [];
412426 foreach ( $ vi ->vlanInterfaces as $ vli ) {
413427 if ( $ vli ->vlan ->private || !$ vli ->vlan ->export_to_ixf ) {
@@ -507,7 +521,7 @@ private function getMemberInfo( string $version, bool $detailed, bool $tags ): a
507521
508522 $ connlist [] = $ conn ;
509523 }
510-
524+
511525 $ memberinfo [ $ cnt ] = [
512526 'asnum ' => $ c ->autsys ,
513527 'member_since ' => \Carbon \Carbon::parse ($ c ->datejoin )->format ( 'Y-m-d ' ).'T00:00:00Z ' ,
@@ -546,10 +560,11 @@ private function getMemberInfo( string $version, bool $detailed, bool $tags ): a
546560 $ memberinfo [ $ cnt ][ 'ixp_manager ' ][ 'resold_via_asn ' ] = $ c ->resellerObject ->autsys ;
547561 }
548562 }
549-
550- $ memberinfo [ $ cnt ][ 'connection_list ' ] = $ connlist ;
551-
552- $ cnt ++;
563+
564+ if ( $ atLeastOneInfraIsConnected ) {
565+ $ memberinfo [ $ cnt ][ 'connection_list ' ] = $ connlist ;
566+ $ cnt ++;
567+ }
553568 }
554569
555570 return $ memberinfo ;
0 commit comments