Skip to content

Commit

Permalink
Migrate routers from config to database
Browse files Browse the repository at this point in the history
Router configurations have been stored in a file since v4.0 with the intention of migrating them to a database. The file was `config/routers.php[.dist]`. This commit does that with standard add / edit / delete functionality.

There is also an artisan command to import the existing entries:

```
./artisan router:import
```

Also includes:

* updating nagios elements
* updating router configuration generation
* updating looking glass

Closes islandbridgenetworks/IXP-Manager#31
  • Loading branch information
barryo committed Apr 20, 2017
1 parent e1516ee commit 2175445
Show file tree
Hide file tree
Showing 41 changed files with 3,242 additions and 1,007 deletions.
17 changes: 8 additions & 9 deletions app/Console/Commands/Router/GenerateConfiguration.php
Expand Up @@ -23,13 +23,13 @@

use IXP\Console\Commands\Command;

use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

use Symfony\Component\Console\Output\OutputInterface;

use IXP\Tasks\Router\ConfigurationGenerator as RouterConfigurationGenerator;

use Entities\{
Router as RouterEntity
};

use D2EM;

/**
* Artisan command to generate router configurations
Expand All @@ -48,7 +48,7 @@ class GenerateConfiguration extends Command {
* @var string
*/
protected $signature = 'router:generate-configuration
{handle : Router handle (from config/routers.php) to use}';
{handle : Router handle (from "Routers" admin action) to use}';

/**
* The console command description.
Expand All @@ -64,13 +64,12 @@ class GenerateConfiguration extends Command {
* @return mixed
*/
public function handle(): int {

if( !config( 'routers.' . $this->argument('handle'), false ) ) {
if( !( $router = D2EM::getRepository( RouterEntity::class )->findOneBy( [ 'handle' => $this->argument('handle') ] ) ) ){
$this->error( "Unknown router handle" );
return -1;
}

echo ( new RouterConfigurationGenerator( $this->argument('handle') ) )->render();
echo ( new RouterConfigurationGenerator( $router ) )->render();
return 0;
}

Expand Down
133 changes: 133 additions & 0 deletions app/Console/Commands/Upgrade/RouterImport.php
@@ -0,0 +1,133 @@
<?php

namespace IXP\Console\Commands\Upgrade;

/*
* Copyright (C) 2009-2017 Internet Neutral Exchange Association Company Limited By Guarantee.
* All Rights Reserved.
*
* This file is part of IXP Manager.
*
* IXP Manager is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version v2.0 of the License.
*
* IXP Manager is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License v2.0
* along with IXP Manager. If not, see:
*
* http://www.gnu.org/licenses/gpl-2.0.html
*/

use IXP\Console\Commands\Command as IXPCommand;
use Entities\{
Router as RouterEntity,
Vlan as VlanEntity
};
use D2EM;

/**
* Class ImportRouters - tool to copy Router from the read file config/routers to the table router
*
* @author Yann Robin <yann@islandbridgenetworks.ie>
* @author Barry O'Donovan <barry@islandbridgenetworks.ie>
* @package IXP\Console\Commands\Upgrade
* @copyright Copyright (C) 2009-2016 Internet Neutral Exchange Association Company Limited By Guarantee
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU GPL V2.0
*/
class RouterImport extends IXPCommand
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'router:import';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Import router definitions from config/routers.php (upgrade to v4.4 requirement)';

/**
* Execute the console command.
*
* @return mixed
*/
public function handle() {
if( !$this->confirm( 'Are you sure you wish to proceed? This command will import the router definitions from config/routers.php to the new dedicated router table in the database ' ) ) {
return 1;
}

// Get the routers list from the file config/routers
if( !( $routers = config( 'routers') ) ) {
$this->error( 'No router definitions have been found' );
return 2;
}

$found = 0;
$imported = 0;
foreach( $routers as $index => $router) {
$found++;

if( D2EM::getRepository( RouterEntity::class )->findBy( [ 'handle' => $index ] ) ) {
$this->alert( "Router with handle {$index} already exists in database, skipping." );
continue;
}

switch ( $router['type'] ) {
case 'RS':
$type = RouterEntity::TYPE_ROUTE_SERVER;
break;
case 'RC':
$type = RouterEntity::TYPE_ROUTE_COLLECTOR;
break;
case 'AS112':
$type = RouterEntity::TYPE_AS112;
break;
default:
$type = RouterEntity::TYPE_OTHER;
}

/** @var VlanEntity $vlan */
if( !($vlan = D2EM::getRepository( VlanEntity::class )->find( $router[ 'vlan_id' ] ) ) ){
$this->alert( 'The VLAN with the ID ' . $router[ 'vlan_id' ] . ' does not exist in the database! The router '. $index . ' can not be imported.' );
continue;
}

/** @var RouterEntity $rt */
$rt = new RouterEntity();
$rt->setVlan( $vlan );
$rt->setHandle( $index );
$rt->setProtocol( $router[ 'protocol' ] );
$rt->setType( $type );
$rt->setName( $router[ 'name' ] );
$rt->setShortName( $router[ 'shortname' ] );
$rt->setRouterId( $router[ 'router_id' ] );
$rt->setPeeringIp( $router[ 'peering_ip' ] );
$rt->setAsn( $router[ 'asn' ] );
$rt->setSoftware( array_search( strtolower( $router[ 'software' ] ),array_map('strtolower', RouterEntity::$SOFTWARES ) ) );
$rt->setMgmtHost( $router[ 'mgmt_ip' ] );
$rt->setApi( $router[ 'api' ] ?? '' );
$rt->setApiType( array_search( strtolower( $router[ 'api_type' ] ?? '' ), array_map('strtolower', RouterEntity::$API_TYPES ) ) );
$rt->setLgAccess( $router[ 'lg_access' ] ?? false );
$rt->setQuarantine( $router[ 'quarantine' ] ?? false );
$rt->setBgpLc( $router[ 'bgp_lc' ] ?? false );
$rt->setSkipMd5( $router['skip_md5'] ?? false );
$rt->setTemplate( $router[ 'template' ] );
D2EM::persist($rt);
$imported++;
}

D2EM::flush();

$this->info( "Migration completed successfully. Found {$found}, imported {$imported}." );
return 0;
}
}
17 changes: 11 additions & 6 deletions app/Console/Kernel.php
Expand Up @@ -2,6 +2,7 @@

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use IXP\Console\Commands\Upgrade\RouterImport;

class Kernel extends ConsoleKernel {

Expand All @@ -11,16 +12,20 @@ class Kernel extends ConsoleKernel {
* @var array
*/
protected $commands = [
'IXP\Console\Commands\Irrdb\UpdateAsnDb',
'IXP\Console\Commands\Irrdb\UpdatePrefixDb',
\IXP\Console\Commands\Irrdb\UpdateAsnDb::class,
\IXP\Console\Commands\Irrdb\UpdatePrefixDb::class,

'IXP\Console\Commands\Router\GenerateConfiguration',
\IXP\Console\Commands\Router\GenerateConfiguration::class,

'IXP\Console\Commands\Upgrade\MrtgTrunkConfig',

\IXP\Console\Commands\Utils\Export\JsonSchema\Post::class,
\IXP\Console\Commands\Utils\UpdateOuiDatabase::class,

\IXP\Console\Commands\Upgrade\MigrateL2Addresses::class,
\IXP\Console\Commands\Upgrade\MrtgTrunkConfig::class,
\IXP\Console\Commands\Upgrade\RouterImport::class,

\IXP\Console\Commands\Utils\Export\JsonSchema\Post::class,


];

/**
Expand Down
6 changes: 3 additions & 3 deletions app/Contracts/LookingGlass.php
Expand Up @@ -3,7 +3,7 @@
declare(strict_types=1);
namespace IXP\Contracts;

use IXP\Utils\Router;
use Entities\Router;


/*
Expand Down Expand Up @@ -43,13 +43,13 @@ interface LookingGlass {
/**
* Set the router object
* @param Router $r
* @return IXP\Services\LookingGlass\BirdsEye For fluent interfaces
* @return LookingGlass For fluent interfaces
*/
public function setRouter( Router $r ): LookingGlass;

/**
* Get the router object
* @return IXP\Utils\Router
* @return Router
*/
public function router(): Router;

Expand Down
33 changes: 16 additions & 17 deletions app/Http/Controllers/Api/V4/NagiosController.php
Expand Up @@ -2,8 +2,8 @@

namespace IXP\Http\Controllers\Api\V4;

use Illuminate\Http\Request;
use IXP\Utils\Routers;
use D2EM;
use Entities\Router as RouterEntity;

class NagiosController extends Controller {

Expand All @@ -18,42 +18,41 @@ class NagiosController extends Controller {
*/
public function birdseyeDaemons( $vlanid = null )
{
$map = [];
$routers = ( new Routers )->filterForApiType('birdseye');
$routers = D2EM::getRepository( RouterEntity::class )->filterForApiType( RouterEntity::API_TYPE_BIRDSEYE );

if( $vlanid ) {
$routers->filterForVlanId($vlanid);
$routers = D2EM::getRepository( RouterEntity::class )->filterCollectionOnVlanId( $routers, $vlanid );
}

if( $routers->isEmpty() ) {
abort( 404, "No definition(s) in config/routers.php for the provided VLAN ID / Bird's Eye API type." );
if( !count($routers) ) {
abort( 404, "No routers for the provided VLAN ID / Bird's Eye API type." );
}

return response()
->view('api/v4/nagios/birdseye-daemons', ['routers' => $routers->getObjects(), 'vlanid' => $vlanid ?? false], 200)
->header('Content-Type', 'text/html; charset=utf-8');
->view('api/v4/nagios/birdseye-daemons', ['routers' => $routers, 'vlanid' => $vlanid ?? false], 200)
->header('Content-Type', 'text/plain; charset=utf-8');
}


public function birdseyeRsBgpSessions( $vlanid = null )
{
$routers = ( new Routers )->filterForApiType('birdseye');
$routers = D2EM::getRepository( RouterEntity::class )->filterForApiType( RouterEntity::API_TYPE_BIRDSEYE );
$routers = D2EM::getRepository( RouterEntity::class )->filterCollectionOnType( $routers, RouterEntity::TYPE_ROUTE_SERVER );

$routers->filterForType('RS');

if( $vlanid ) {
$routers->filterForVlanId($vlanid);
$routers = D2EM::getRepository( RouterEntity::class )->filterCollectionOnVlanId( $routers, $vlanid );
}

if( $routers->isEmpty() ) {
if( !count( $routers ) ) {
abort( 404, "No suitable definition(s) in config/routers.php found." );
}

$map = [];
$vlans = [];

foreach( $routers->getObjects() as $h => $router ) {

foreach( $routers as $h => $router ) {

$h = $router->getHandle();
if( !$router->hasApi() ) {
continue;
}
Expand Down Expand Up @@ -113,7 +112,7 @@ public function birdseyeRsBgpSessions( $vlanid = null )

return response()
->view('api/v4/nagios/birdseye-rs-bgp-daemons', ['map' => $map, 'vlanid' => $vlanid ?? false], 200)
->header('Content-Type', 'text/html; charset=utf-8');
->header('Content-Type', 'text/plain; charset=utf-8');
}

}
16 changes: 10 additions & 6 deletions app/Http/Controllers/Api/V4/RouterController.php
Expand Up @@ -24,10 +24,15 @@
* http://www.gnu.org/licenses/gpl-2.0.html
*/

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use IXP\Tasks\Router\ConfigurationGenerator as RouterConfigurationGenerator;

use Entities\{
Router as RouterEntity
};

use D2EM;

/**
* RouterController
*
Expand All @@ -42,20 +47,19 @@ class RouterController extends Controller {
/**
* Generate a configuration.
*
* This just takes one argument: the router handle to generate the configuration for. All
* other parameters are defined by the handle's array in config/router.php.
* This just takes one argument: the router handle to generate the configuration for.
*
* @return Response
*/
public function genConfig( string $handle ): Response {
if( !config( 'routers.' . $handle, false ) ) {
if( !( $router = D2EM::getRepository( RouterEntity::class )->findOneBy( [ 'handle' => $handle ] ) ) ) {
abort( 404, "Unknown router handle" );
}

$configView = ( new RouterConfigurationGenerator( $handle ) )->render();
$configView = ( new RouterConfigurationGenerator( $router ) )->render();

return response( $configView->render(), 200 )
->header('Content-Type', 'text/html; charset=utf-8');
->header('Content-Type', 'text/plain; charset=utf-8');
}

}

0 comments on commit 2175445

Please sign in to comment.