diff --git a/bin/plugin/open/groupList b/bin/plugin/open/groupList index 5d10bab..ca6f7ae 100755 --- a/bin/plugin/open/groupList +++ b/bin/plugin/open/groupList @@ -9,17 +9,24 @@ use OVH::Result; use OVH::Bastion; use OVH::Bastion::Plugin qw( :DEFAULT help ); -my ($all); my $remainingOptions = OVH::Bastion::Plugin::begin( - argv => \@ARGV, - header => "group list", - options => {'all' => \$all}, + argv => \@ARGV, + header => "group list", + options => { + 'all' => \my $all, + 'exclude=s' => \my @excludes, + 'include=s' => \my @includes, + }, helptext => <<'EOF', List the groups available on this bastion -Usage: --osh SCRIPT_NAME [--all] +Usage: --osh SCRIPT_NAME [--all] [--exclude|--include WILDCARD [--exclude|--include WILDCARD ..]] - --all List all groups, even those to which you don't have access + --all List all groups, even those to which you don't have access + --include WILDCARD Only list groups that match the given WILDCARD string, '*' and '?' are recognized, + this option can be used multiple times to refine results. + --exclude WILDCARD Omit groups that match the given WILDCARD string, '*' and '?' are recognized, + can be used multiple times. Note that --exclude takes precedence over --include EOF ); @@ -28,8 +35,18 @@ my $fnret; $fnret = OVH::Bastion::get_group_list(groupType => "key"); $fnret or osh_exit $fnret; +my $includere = OVH::Bastion::build_re_from_wildcards(wildcards => \@includes)->value; +my $excludere = OVH::Bastion::build_re_from_wildcards(wildcards => \@excludes)->value; + my $result_hash = {}; foreach my $name (sort keys %{$fnret->value}) { + + # if we have excludes, match name against the built regex + next if ($excludere && $name =~ $excludere); + + # same for includes + next if ($includere && $name !~ $includere); + my @flags; push @flags, 'owner' if OVH::Bastion::is_group_owner(group => $name, cache => 1); push @flags, 'gatekeeper' if OVH::Bastion::is_group_gatekeeper(group => $name, cache => 1); diff --git a/bin/plugin/restricted/accountList b/bin/plugin/restricted/accountList index a97b622..250b43f 100755 --- a/bin/plugin/restricted/accountList +++ b/bin/plugin/restricted/accountList @@ -17,6 +17,8 @@ my $remainingOptions = OVH::Bastion::Plugin::begin( "realm-only" => \my $realmOnly, "account=s" => \my $account, "audit" => \my $audit, + 'exclude=s' => \my @excludes, + 'include=s' => \my @includes, }, helptext => <<'EOF', List the bastion accounts @@ -26,6 +28,10 @@ Usage: --osh SCRIPT_NAME [--account ACCOUNT] [--inactive-only] [--audit] --account ACCOUNT Only list the specified account. This is an easy way to check whether the account exists --inactive-only Only list inactive accounts --audit Show more verbose information (SLOW!), you need to be a bastion auditor + --include WILDCARD Only list accounts that match the given WILDCARD string, '*' and '?' are recognized, + this option can be used multiple times to refine results. + --exclude WILDCARD Omit accounts that match the given WILDCARD string, '*' and '?' are recognized, + can be used multiple times. Note that --exclude takes precedence over --include EOF ); @@ -63,10 +69,20 @@ if ($audit) { $fnretPassword = OVH::Bastion::helper(cmd => \@command); } +# if we have excludes and/or includes, transform those into regexes +my $includere = OVH::Bastion::build_re_from_wildcards(wildcards => \@includes)->value; +my $excludere = OVH::Bastion::build_re_from_wildcards(wildcards => \@excludes)->value; + my $result_hash = {}; foreach my $account (sort keys %$accounts) { - my %states; + # if we have excludes, match name against the built regex + next if ($excludere && $account =~ $excludere); + + # same for includes + next if ($includere && $account !~ $includere); + + my %states; $states{'is_active'} = undef; $fnret = OVH::Bastion::is_account_active(account => $account); if ($fnret->is_ok) { diff --git a/lib/perl/OVH/Bastion/allowkeeper.inc b/lib/perl/OVH/Bastion/allowkeeper.inc index 96dc14f..3e5d673 100644 --- a/lib/perl/OVH/Bastion/allowkeeper.inc +++ b/lib/perl/OVH/Bastion/allowkeeper.inc @@ -1046,4 +1046,25 @@ sub is_valid_ttl { return R('KO_INVALID_PARAMETER', msg => "Invalid TTL ($ttl), expected an amount of seconds, or a duration string such as '2d8h15m'"); } +# used by groupList and accountList +sub build_re_from_wildcards { + my %params = @_; + my $wildcards = $params{'wildcards'}; + + # to avoid modifying the caller's array + my @relist = @$wildcards; + + # qr// is true, so return undef if there's nothing to build + return R('OK', value => undef) if !@relist; + + for (@relist) { + $_ = quotemeta; + s/\\\*/.*/g; + s/\\\?/./g; + $_ = '^' . $_ . '$'; + } + my $stringified = join("|", @relist); + return R('OK', value => qr/$stringified/); +} + 1;