#1064 implement tags in database and ACL
This commit is contained in:
@@ -11,7 +11,7 @@ __PACKAGE__->load_namespaces(
|
|||||||
);
|
);
|
||||||
|
|
||||||
our # try to hide from kwalitee
|
our # try to hide from kwalitee
|
||||||
$VERSION = 80; # schema version used for upgrades, keep as integer
|
$VERSION = 81; # schema version used for upgrades, keep as integer
|
||||||
|
|
||||||
use Path::Class;
|
use Path::Class;
|
||||||
use File::ShareDir 'dist_dir';
|
use File::ShareDir 'dist_dir';
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ __PACKAGE__->add_columns(
|
|||||||
{ data_type => "boolean", is_nullable => 1 },
|
{ data_type => "boolean", is_nullable => 1 },
|
||||||
"custom_fields",
|
"custom_fields",
|
||||||
{ data_type => "jsonb", is_nullable => 0, default_value => \"{}" },
|
{ data_type => "jsonb", is_nullable => 0, default_value => \"{}" },
|
||||||
|
"tags",
|
||||||
|
{ data_type => "text[]", is_nullable => 0, default_value => \"'{}'::text[]" },
|
||||||
);
|
);
|
||||||
__PACKAGE__->set_primary_key("ip");
|
__PACKAGE__->set_primary_key("ip");
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ __PACKAGE__->add_columns(
|
|||||||
{ data_type => "bigint", is_nullable => 1 },
|
{ data_type => "bigint", is_nullable => 1 },
|
||||||
"custom_fields",
|
"custom_fields",
|
||||||
{ data_type => "jsonb", is_nullable => 0, default_value => \"{}" },
|
{ data_type => "jsonb", is_nullable => 0, default_value => \"{}" },
|
||||||
|
"tags",
|
||||||
|
{ data_type => "text[]", is_nullable => 0, default_value => \"'{}'::text[]" },
|
||||||
);
|
);
|
||||||
__PACKAGE__->set_primary_key("port", "ip");
|
__PACKAGE__->set_primary_key("port", "ip");
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,33 @@ sub check_acl {
|
|||||||
next RULE;
|
next RULE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($rule =~ m/^tag:(.+)$/) {
|
||||||
|
my $tag = $1;
|
||||||
|
my $found = false;
|
||||||
|
|
||||||
|
ITEM: foreach my $item (@$things) {
|
||||||
|
if (blessed $item) {
|
||||||
|
if ($neg xor ($item->can('tags') and ref [] eq ref $item->tags
|
||||||
|
and scalar grep {$_ eq $tag} @{ $item->tags })) {
|
||||||
|
return true if not $all;
|
||||||
|
$found = true;
|
||||||
|
last ITEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif (ref {} eq ref $item) {
|
||||||
|
if ($neg xor (exists $item->{'tags'} and ref [] eq ref $item->{'tags'}
|
||||||
|
and scalar grep {$_ eq $tag} @{ $item->{'tags'} })) {
|
||||||
|
return true if not $all;
|
||||||
|
$found = true;
|
||||||
|
last ITEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false if $all and not $found;
|
||||||
|
next RULE;
|
||||||
|
}
|
||||||
|
|
||||||
# prop:val
|
# prop:val
|
||||||
# with a check that prop isn't just the first part of a v6 addr
|
# with a check that prop isn't just the first part of a v6 addr
|
||||||
if ($rule =~ m/^([^:]+):(.*)$/ and $1 !~ m/^[a-f0-9]+$/i) {
|
if ($rule =~ m/^([^:]+):(.*)$/ and $1 !~ m/^[a-f0-9]+$/i) {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE device ADD COLUMN "tags" text[] DEFAULT '{}' NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE device_port ADD COLUMN "tags" text[] DEFAULT '{}' NOT NULL;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -150,6 +150,12 @@ my $dp = App::Netdisco::DB->resultset('DevicePort')->new_result({
|
|||||||
ip => '127.0.0.1',
|
ip => '127.0.0.1',
|
||||||
port => 'TenGigabitEthernet1/10',
|
port => 'TenGigabitEthernet1/10',
|
||||||
type => 'l3ipvlan',
|
type => 'l3ipvlan',
|
||||||
|
tags => [qw/ foo bar baz /],
|
||||||
|
});
|
||||||
|
|
||||||
|
my $d = App::Netdisco::DB->resultset('Device')->new_result({
|
||||||
|
ip => '127.0.0.1',
|
||||||
|
tags => [qw/ quux /],
|
||||||
});
|
});
|
||||||
|
|
||||||
# device properties
|
# device properties
|
||||||
@@ -167,6 +173,7 @@ is(acl_matches([$dip2, $dp], ['foobar:xyz']), 0, '2obj unknown property');
|
|||||||
|
|
||||||
my $dip2c = { $dip2->get_inflated_columns };
|
my $dip2c = { $dip2->get_inflated_columns };
|
||||||
my $dpc = { $dp->get_inflated_columns };
|
my $dpc = { $dp->get_inflated_columns };
|
||||||
|
my $dc = { $d->get_inflated_columns };
|
||||||
|
|
||||||
# device properties
|
# device properties
|
||||||
ok(acl_matches([$dip2c, $dpc], [$conf[23]]), 'hh instance anon property deviceport:alias');
|
ok(acl_matches([$dip2c, $dpc], [$conf[23]]), 'hh instance anon property deviceport:alias');
|
||||||
@@ -204,4 +211,14 @@ ok(acl_matches([$dip2c, $dp], ['remote_ip:']), 'ho related item field empty');
|
|||||||
ok(acl_matches([$dip2c, $dp], ['!type:']), 'ho related item field not empty');
|
ok(acl_matches([$dip2c, $dp], ['!type:']), 'ho related item field not empty');
|
||||||
is(acl_matches([$dip2c, $dp], ['foobar:xyz']), 0, 'ho unknown property');
|
is(acl_matches([$dip2c, $dp], ['foobar:xyz']), 0, 'ho unknown property');
|
||||||
|
|
||||||
|
# tags
|
||||||
|
|
||||||
|
ok(acl_matches([$dip2, $dp], ['tag:foo']), '2obj tag exists');
|
||||||
|
ok(acl_matches([$dip2, $dp], ['!tag:quux']), '2obj tag not existing');
|
||||||
|
is(acl_matches([$dp], ['tag:quux']), 0, '1obh tag does not exist');
|
||||||
|
|
||||||
|
ok(acl_matches([$dip2c, $dpc], ['tag:foo']), 'hh tag exists');
|
||||||
|
ok(acl_matches([$dip2c, $dpc], ['!tag:quux']), 'hh tag not existing');
|
||||||
|
is(acl_matches([$dpc], ['tag:quux']), 0, 'hh tag does not exist');
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|||||||
Reference in New Issue
Block a user