use
Dancer
qw/:syntax :script/
;
our
@EXPORT
= ();
our
@EXPORT_OK
=
qw/
port_acl_by_role_check port_acl_check
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
);
sub
port_acl_by_role_check {
my
(
$port
,
$device
,
$user
) =
@_
;
return
true
if
$ENV
{ND2_DO_FORCE};
if
(
$device
and
ref
$device
and
$user
) {
$user
=
ref
$user
?
$user
:
schema(
'netdisco'
)->resultset(
'User'
)
->find({
username
=>
$user
});
return
false
unless
$user
;
my
$username
=
$user
->username;
return
true
if
(
$user
->admin and
$user
->port_control);
my
$role
=
$user
->portctl_role;
my
$acl
=
$role
? setting(
'portctl_by_role'
)->{
$role
} :
undef
;
if
(
$acl
and (
ref
$acl
eq
q{}
or
ref
$acl
eq
ref
[])) {
return
true
if
acl_matches(
$device
,
$acl
);
}
elsif
(
$acl
and
ref
$acl
eq
ref
{}) {
my
$found
= false;
foreach
my
$key
(
sort
keys
%$acl
) {
next
unless
$key
and
$acl
->{
$key
};
if
(acl_matches(
$device
,
$key
)
and acl_matches(
$port
,
$acl
->{
$key
})) {
$found
= true;
last
;
}
}
return
true
if
$found
;
}
elsif
(
$role
) {
return
true
if
$user
->port_control;
}
return
$user
->port_control;
}
return
false;
}
sub
port_acl_check {
my
(
$port
,
$device
,
$user
) =
@_
;
my
$ip
=
$port
->ip;
return
false
if
acl_matches(
$ip
,
'portctl_no'
);
return
false
unless
acl_matches_only(
$ip
,
'portctl_only'
);
return
true;
}
sub
port_acl_service {
my
(
$port
,
$device
,
$user
) =
@_
;
return
false
if
setting(
'portctl_nameonly'
);
return
false
if
setting(
'portctl_nowaps'
) and port_has_wap(
$port
);
return
false
if
setting(
'portctl_nophones'
) and port_has_phone(
$port
);
return
false
if
(not setting(
'portctl_uplinks'
)) and
((
$port
->is_uplink or
$port
->remote_type or is_vlan_subinterface(
$port
)) and not
(port_has_wap(
$port
) or port_has_phone(
$port
)));
return
false
if
not port_acl_check(
@_
);
return
port_acl_by_role_check(
@_
);
}
sub
port_acl_pvid {
my
(
$port
,
$device
,
$user
) =
@_
;
return
false
unless
setting(
'portctl_native_vlan'
);
return
port_acl_service(
@_
);
}
sub
port_acl_name {
goto
&port_acl_by_role_check
}
sub
get_port {
my
(
$device
,
$portname
) =
@_
;
$device
= get_device(
$device
);
return
unless
$device
and
$device
->in_storage;
my
$port
= schema(vars->{
'tenant'
})->resultset(
'DevicePort'
)->with_properties
->find({
ip
=>
$device
->ip,
port
=>
$portname
});
return
unless
$port
and
$port
->in_storage;
return
(
wantarray
? (
$device
,
$port
) :
$port
);
}
sub
get_iid {
my
(
$info
,
$port
) =
@_
;
$port
=
$port
->port
if
ref
$port
;
my
$interfaces
=
$info
->interfaces;
my
%rev_if
=
reverse
%$interfaces
;
my
$iid
=
$rev_if
{
$port
};
return
$iid
;
}
sub
get_powerid {
my
(
$info
,
$port
) =
@_
;
$port
=
$port
->port
if
ref
$port
;
my
$iid
= get_iid(
$info
,
$port
)
or
return
undef
;
my
$p_interfaces
=
$info
->peth_port_ifindex;
my
%rev_p_if
=
reverse
%$p_interfaces
;
my
$powerid
=
$rev_p_if
{
$iid
};
return
$powerid
;
}
sub
is_vlan_subinterface {
my
$port
=
shift
;
return
true
if
$port
->has_subinterfaces;
my
$is_vlan
= ((
$port
->type and
$port
->type =~ /^(53|propVirtual|l2vlan|l3ipvlan|135|136|137)$/i)
or (
$port
->port and
$port
->port =~ /vlan/i)
or (
$port
->descr and
$port
->descr =~ /vlan/i)) ? 1 : 0;
return
$is_vlan
;
}
sub
port_has_phone {
my
$row
=
shift
;
return
$row
->remote_is_phone
if
$row
->can(
'remote_is_phone'
);
my
$properties
=
$row
->properties;
return
(
$properties
?
$properties
->remote_is_phone :
undef
);
}
sub
port_has_wap {
my
$row
=
shift
;
return
$row
->remote_is_wap
if
$row
->can(
'remote_is_wap'
);
my
$properties
=
$row
->properties;
return
(
$properties
?
$properties
->remote_is_wap :
undef
);
}
sub
munge_highspeed {
my
$speed
=
shift
;
my
$fmt
=
"%d Mbps"
;
if
(
$speed
> 9999999 ) {
$fmt
=
"%d Tbps"
;
$speed
/= 1000000;
}
elsif
(
$speed
> 999999 ) {
$fmt
=
"%.1f Tbps"
;
$speed
/= 1000000.0;
}
elsif
(
$speed
> 9999 ) {
$fmt
=
"%d Gbps"
;
$speed
/= 1000;
}
elsif
(
$speed
> 999 ) {
$fmt
=
"%.1f Gbps"
;
$speed
/= 1000.0;
}
return
sprintf
(
$fmt
,
$speed
);
}
sub
to_speed {
my
$speed
=
shift
or
return
''
;
return
$speed
if
$speed
=~ m/\D/;
(
$speed
= munge_highspeed(
$speed
/ 1_000_000)) =~ s/\.0 ?//g;
return
$speed
;
}
1;