Improve our parent/children identification with points, fix our testing that was failing with NULLs and asserted out. Added zone:check so that's its easier to identify parent for FTNs

This commit is contained in:
2023-12-11 18:31:38 +11:00
parent 247cf614f3
commit 541f612446
4 changed files with 229 additions and 40 deletions

View File

@@ -0,0 +1,100 @@
<?php
namespace App\Console\Commands;
use App\Models\{Domain};
use App\Models\Address;
use Illuminate\Console\Command;
class ZoneCheck extends Command
{
protected $signature = 'zone:check'
.' {domain : Domain Name}'
.' {--Z|zone= : Zone}';
protected $description = 'Check that the addresses in a zone are configured correctly';
public function handle()
{
$do = Domain::where('name',$this->argument('domain'))->singleOrFail();
foreach ($do->zones as $zo) {
if ($this->option('zone') && ($this->option('zone') != $zo->zone_id))
continue;
$this->warn('Zone: '.$zo->zone_id);
$this->info(sprintf('- Our address(es): %s',our_address($zo)->pluck('ftn4d')->join(',')));
$this->table(['id','ftn','role','parent','region_id','host_id','hub_id','system','notes'],$zo->addresses()->FTNorder()->active()->with(['system'])->get()->transform(function($item) {
return [
'id'=>$item->id,
'ftn'=>$item->ftn4d,
'role'=>$item->role_name,
'parent'=>$item->parent()?->ftn4d,
'region_id'=>$item->region_id,
'host_id'=>$item->host_id,
'hub_id'=>$item->hub_id,
'system'=>$item->system->name,
'notes'=>$this->check($item),
];
}));
}
return Command::SUCCESS;
}
/**
* Check that an address is defined correctly
*
* @param Address $ao
* @return string
*/
private function check(Address $ao): string
{
// ZC address
if ($ao->role === Address::NODE_ZC) {
if (($ao->region_id === 0) && ($ao->host_id === 0) && ($ao->node_id === 0) && is_null($ao->hub_id) && ($ao->point_id === 0))
return 'OK';
else
return 'INVALID ZC address';
}
// RC address
if ($ao->role === Address::NODE_RC) {
if ($ao->region_id && ($ao->region_id === $ao->host_id) && ($ao->node_id === 0) && is_null($ao->hub_id) && ($ao->point_id === 0))
return 'OK';
else
return 'INVALID RC address';
}
// NC address
if ($ao->role === Address::NODE_NC) {
if (($ao->node_id !== 0) && is_null($ao->hub_id) && ($ao->point_id === 0))
return 'OK';
else
return 'INVALID NC address';
}
// HUB address
if ($ao->role === Address::NODE_HC) {
if (($ao->node_id !== 0) && is_null($ao->hub_id) && ($ao->point_id === 0))
return 'OK';
else
return 'INVALID HUB address';
}
// POINT address
if ($ao->role === Address::NODE_POINT) {
if ($ao->point_id !== 0)
return 'OK';
else
return 'INVALID POINT address';
}
if ($ao->region_id && ($ao->host_id === 0))
return 'INVALID REGION NODE';
return '';
}
}

View File

@@ -150,7 +150,6 @@ class Address extends Model
/**
* Find children dependent on this record
* @todo If bosses are defined here, and points, then mail to a point goes to it's boss
*/
public function children()
{
@@ -194,9 +193,18 @@ class Address extends Model
case self::NODE_PVT:
case self::NODE_HOLD:
case self::NODE_DOWN:
case self::NODE_POINT:
case self::NODE_UNKNOWN:
// Nodes dont have children, but must return a relationship instance
// Identify our children.
$children = self::select('addresses.*')
->where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',$this->host_id)
->where('node_id',$this->node_id)
->where('point_id','<>',0);
break;
case self::NODE_POINT:
// Points dont have children, but must return a relationship instance
return $this->hasOne(self::class,NULL,'void');
default:
@@ -298,14 +306,17 @@ class Address extends Model
*
* @return Address|null
* @throws \Exception
* @todo Dont include points in this
*/
public function parent(): ?Address
{
// If we are have session password, then we dont have a parent
// If we have session password, then we are the parent
if ($this->session('sespass'))
return $this;
// If it is our address
if (our_address()->contains($this))
return NULL;
switch ($this->role) {
// ZCs dont have parents, but we may have a default
case self::NODE_ZC:
@@ -326,15 +337,15 @@ class Address extends Model
// Hosts
case self::NODE_NC:
// See if we have a RC
// See if we have an RC
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',0)
->where('host_id',$this->region_id)
->where('node_id',0)
->single();
if (! $parent) {
// See if we have a RC
// See if we have an ZC
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',0)
->where('host_id',0)
@@ -351,22 +362,27 @@ class Address extends Model
case self::NODE_PVT:
case self::NODE_HOLD:
case self::NODE_DOWN:
case self::NODE_UNKNOWN:
// If we are a child of a hub, then check our hub
$parent = ($this->hub_id
? self::where('id',$this->hub_id)
: self::where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',$this->host_id)
->where('node_id',0)
->where('role','<',$this->role))
->where('role','<',self::NODE_HC))
->active()
->single();
break;
case self::NODE_UNKNOWN:
case self::NODE_POINT:
// @todo Points - if the boss is defined, we should return it.
return NULL;
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',$this->host_id)
->where('node_id',$this->node_id)
->where('point_id',0)
->active()
->single();
break;
default:
throw new \Exception(sprintf('Unknown role: %s (%d)',serialize($this->role),$this->id));