App-Netdisco
view release on metacpan or search on metacpan
lib/App/Netdisco/Util/Port.pm view on Meta::CPAN
package App::Netdisco::Util::Port;
use Dancer qw/:syntax :script/;
use Dancer::Plugin::DBIC 'schema';
use Dancer::Plugin::Auth::Extensible;
use App::Netdisco::Util::Device 'get_device';
use App::Netdisco::Util::Permission qw/acl_matches acl_matches_only/;
use base 'Exporter';
our @EXPORT = ();
our @EXPORT_OK = qw/
sync_portctl_roles
port_acl_service port_acl_pvid port_acl_name
get_port get_iid get_powerid
is_vlan_subinterface port_has_phone port_has_wap
to_speed
/;
our %EXPORT_TAGS = (all => \@EXPORT_OK);
=head1 NAME
App::Netdisco::Util::Port
=head1 DESCRIPTION
A set of helper subroutines to support parts of the Netdisco application.
There are no default exports, however the C<:all> tag will export all
subroutines.
=head1 EXPORT_OK
=head2 sync_portctl_roles()
Loads Port Control Roles from the database and merges them into the
C<portctl_role> config. This should only be done lazily and near to the
time of use, to be efficient and also to get latest ACL settings.
If there exists an entry in C<portctl_role> config from C<deployment.yml>
with the same name as a database role, then the database role overwrites
it. If such a role is removed, then a backup of the original is restored.
=cut
sub sync_portctl_roles {
my @db_roles = schema(vars->{'tenant'})
->resultset('PortCtlRole')->role_names;
config->{'portctl_by_role'} = {};
foreach my $role (sort {$a cmp $b} keys %{ setting('portctl_by_role_shadow') }) {
config->{'portctl_by_role'}->{$role}
= (setting('portctl_by_role_shadow')->{$role} || '!group:__ANY__');
}
foreach my $role (@db_roles) {
my @rows = schema(vars->{'tenant'})->resultset('PortCtlRole')
->search({ role_name => $role },
{ prefetch => [qw/device_acl port_acl/], order_by => 'me.id' })->all;
config->{'portctl_by_role'}->{$role} = {};
foreach my $pair (@rows) {
#Â convert LHS device ACLs to named groups
my $group = 'synthesized_group_'. $pair->device_acl->id;
config->{'host_groups'}->{$group} = $pair->device_acl->rules;
config->{'portctl_by_role'}->{$role}->{'group:'. $group}
= $pair->port_acl->rules;
}
}
}
=head2 port_acl_by_role_check( $port, $device?, $user? )
=over 4
=item *
Permission check on C<portctl_by_role> if the device and user are provided. A
bare username will be promoted to a user instance.
=back
Will return false if these checks fail, otherwise true.
=cut
sub port_acl_by_role_check {
my ($port, $device, $user) = @_;
#Â skip user acls for netdisco-do --force jobs
#Â this avoids the need to create a netdisco user in the DB and give rights
return true if $ENV{ND2_DO_FORCE};
#Â portctl_by_role check
if ($device and ref $device and $user) {
$user = ref $user ? $user :
schema('netdisco')->resultset('User')
->find({ username => $user });
return false unless $user;
#Â special case admin user allowed to continue, because
# they can submit port control jobs
( run in 1.268 second using v1.01-cache-2.11-cpan-df04353d9ac )