You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
761 lines
26 KiB
761 lines
26 KiB
use strict;
|
|
|
|
eval 'use lib "/home/rkrenn/sipwise/git/sipwise-base/lib";';
|
|
eval 'use lib "/home/rkrenn/sipwise/git/ngcp-panel/lib";';
|
|
eval 'use NGCP::Panel::Utils::Message qw();';
|
|
my $panel_util_message_loaded = 1;
|
|
if ($@) {
|
|
warn('cannot load NGCP::Panel::Utils::Message');
|
|
$panel_util_message_loaded = 0;
|
|
}
|
|
|
|
use File::Find qw();
|
|
use File::Basename qw();
|
|
use File::Spec qw();
|
|
use YAML::XS;
|
|
|
|
my @perlfileextensions = ('.pl','.pm');
|
|
my $rperlextensions = join('|',map { quotemeta($_); } @perlfileextensions);
|
|
|
|
my $root = "/home/rkrenn/sipwise/git/ngcp-panel/";
|
|
my @dirstoskip = ();
|
|
push @dirstoskip,$root."sandbox/";
|
|
|
|
my @filestoskip = ();
|
|
push @filestoskip,$root."lib/NGCP/Panel/Utils/Message.pm";
|
|
|
|
my %dirsdone;
|
|
my %mock_objs = ();
|
|
my %result = (
|
|
'panel-debug.log' => [],
|
|
'api.log' => [],
|
|
'panel.log' => [],
|
|
);
|
|
my $messages_count;
|
|
my $invocations_count;
|
|
my %distinct_variables;
|
|
my $extracted_message = undef;
|
|
my $is_sensitive = 0;
|
|
my $message_role = undef;
|
|
|
|
scancatalystlog();
|
|
scanmessageslog();
|
|
write_ymls();
|
|
exit();
|
|
|
|
sub scancatalystlog {
|
|
|
|
$messages_count = 0;
|
|
$invocations_count = 0;
|
|
%dirsdone = ();
|
|
%distinct_variables = ();
|
|
File::Find::find({ wanted => \&scancatalystlog_dir_names, follow => 1 }, $root);
|
|
print "scan for \$c->log:\n method invocations: $invocations_count\n identified messages: $messages_count\n distinct variables: " . (scalar keys %distinct_variables) . "\n";
|
|
|
|
}
|
|
|
|
sub scancatalystlog_dir_names {
|
|
|
|
_scandirs(sub {
|
|
my $dir = shift;
|
|
_scandirfiles($dir,0,sub {
|
|
my ($line,$inputfilename,$inputfiledir,$inputfilesuffix,$next_line) = @_;
|
|
if ($line =~ /->log(\(\))?->(debug|info|warn|error|fatal)/
|
|
and substr(_trim($line),0,1) ne '#') {
|
|
my $method = $2;
|
|
my $source_file_name = _get_source_file_name($inputfilename,$inputfiledir,$inputfilesuffix);
|
|
my $message = _trim($line);
|
|
$message =~ s/^\$.+->log(\(\))?->$method\(//;
|
|
$message =~ s/(\s*#.+)?$//;
|
|
while ($message !~ /;$/) {
|
|
my $next_line = &$next_line();
|
|
next if substr(_trim($next_line),0,1) eq '#';
|
|
$next_line = _trim($next_line);
|
|
$next_line =~ s/(\s*#.+)?$//;
|
|
$message .= $next_line;
|
|
}
|
|
$message =~ s/\)(\s+(if|unless)[^;]+)?;(\s*#.+)?$//;
|
|
_dispatch_logfile(_list_variables({
|
|
gdpr_status => ($message =~ /->qs\(/ ? 2 : 0),
|
|
level => $method,
|
|
log_line => $message,
|
|
source_file => $source_file_name,
|
|
}));
|
|
#print $message . "\n";
|
|
$messages_count++;
|
|
$invocations_count++;
|
|
}
|
|
return 1;
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
sub scanmessageslog {
|
|
|
|
$messages_count = 0;
|
|
$invocations_count = 0;
|
|
%dirsdone = ();
|
|
%distinct_variables = ();
|
|
File::Find::find({ wanted => \&scanmessageslog_dir_names, follow => 1 }, $root);
|
|
print "scan for NGCP::Panel::Utils::Message:\n method invocations: $invocations_count\n identified messages: $messages_count\n distinct variables: " . (scalar keys %distinct_variables) . "\n";
|
|
|
|
}
|
|
|
|
sub scanmessageslog_dir_names {
|
|
|
|
_scandirs(sub {
|
|
my $dir = shift;
|
|
_scandirfiles($dir,1,sub {
|
|
my ($data_ref,$inputfilename,$inputfiledir,$inputfilesuffix) = @_;
|
|
while ($$data_ref =~ /((\s*#\s*)?NGCP::Panel::Utils::Message::(info|error)\([^;]+\)(\s+(if|unless)[^;]+)?;)/gm) {
|
|
my $line = $1;
|
|
my $method = $3;
|
|
next if substr(_trim($line),0,1) eq '#';
|
|
$line =~ s/^NGCP::Panel::Utils::Message::(info|error)\(/{/m;
|
|
$line =~ s/\)(\s+(if|unless)[^;]+)?;/}/m;
|
|
my $source_file_name = _get_source_file_name($inputfilename,$inputfiledir,$inputfilesuffix);
|
|
my %messages = _extract_messages($line,$method);
|
|
foreach my $message (keys %messages) {
|
|
_dispatch_logfile(_list_variables({
|
|
gdpr_status => ($messages{$message} ? 2 : 0),
|
|
level => $method,
|
|
log_line => $message,
|
|
source_file => $source_file_name,
|
|
}));
|
|
$messages_count++;
|
|
#print $count . ". " . $message . "\n\n";
|
|
}
|
|
$invocations_count++;
|
|
}
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
sub _scandirs {
|
|
|
|
my ($scandirfiles_code) = @_;
|
|
my $path = $File::Find::dir;
|
|
if (-d $path) {
|
|
my $dir = $path . '/';
|
|
if (not $dirsdone{$dir}
|
|
and not scalar grep { substr($dir, 0, length($_)) eq $_; } @dirstoskip) {
|
|
&$scandirfiles_code($dir);
|
|
}
|
|
$dirsdone{$dir} = 1;
|
|
}
|
|
}
|
|
|
|
sub _scandirfiles {
|
|
|
|
my ($inputdir,$slurp,$code) = @_;
|
|
|
|
local *DIR;
|
|
if (not opendir(DIR, $inputdir)) {
|
|
die('cannot opendir ' . $inputdir . ': ' . $!);
|
|
}
|
|
my @files = grep { /$rperlextensions$/ && -f $inputdir . $_} readdir(DIR);
|
|
closedir DIR;
|
|
return unless (scalar @files) > 0;
|
|
foreach my $file (@files) {
|
|
my $inputfilepath = $inputdir . $file;
|
|
next if grep { $_ eq $inputfilepath; } @filestoskip;
|
|
my ($inputfilename,$inputfiledir,$inputfilesuffix) = File::Basename::fileparse($inputfilepath, $rperlextensions);
|
|
local *FILE;
|
|
if (not open (FILE,'<' . $inputfilepath)) {
|
|
die('cannot open file ' . $inputfilepath . ': ' . $!);
|
|
}
|
|
if ($slurp) {
|
|
my $line_terminator = $/;
|
|
$/ = undef;
|
|
my $data = <FILE>;
|
|
&$code(\$data,$inputfilename,$inputfiledir,$inputfilesuffix);
|
|
$/ = $line_terminator;
|
|
} else {
|
|
while (<FILE>) {
|
|
last unless &$code($_,$inputfilename,$inputfiledir,$inputfilesuffix, sub {
|
|
<FILE>;
|
|
});
|
|
}
|
|
}
|
|
close(FILE);
|
|
}
|
|
|
|
}
|
|
|
|
sub _trim {
|
|
my $str = shift;
|
|
$str =~ s/^\s+//g;
|
|
$str =~ s/\s+$//g;
|
|
return $str;
|
|
}
|
|
|
|
sub _extract_messages {
|
|
my ($message_invocation,$method) = @_;
|
|
my %dupe_results = ();
|
|
foreach my $vector (_generate_combinations(
|
|
[
|
|
{ role => 'subscriber' },
|
|
],[
|
|
{ e => '$e' },
|
|
],[
|
|
{ error => undef },
|
|
{ error => '$error' },
|
|
{ error => _create_mock('error',
|
|
_error => '$error->{error}',
|
|
_description => '$error->{description}',
|
|
_create_sub_mock('type'),
|
|
_create_sub_mock('info'),
|
|
) },
|
|
],
|
|
)) {
|
|
my %vector = map { %{$_}; } @$vector;
|
|
my $args = _deserialize_messagesargs($message_invocation,%vector);
|
|
if ($args and _run_message($method,$args,%vector)) {
|
|
if ($extracted_message
|
|
and index($extracted_message,'=HASH(0x') < 0) { # filter out nonsense vector stringifications
|
|
$dupe_results{$extracted_message} = $dupe_results{$extracted_message} || $is_sensitive;
|
|
}
|
|
}
|
|
}
|
|
return %dupe_results;
|
|
}
|
|
|
|
sub _run_message {
|
|
my $method = shift;
|
|
my $args = shift;
|
|
my %_params = @_;
|
|
($message_role) = @_params{qw/
|
|
role
|
|
/};
|
|
$extracted_message = undef;
|
|
$is_sensitive = 0;
|
|
$args->{flash} = 0;
|
|
$args->{stash} = 0;
|
|
$args->{c} = _create_mock('_c',
|
|
_stash => {
|
|
|
|
},
|
|
stash => sub {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
return $self->{stash}->{$key} if $key;
|
|
return $self->{stash};
|
|
},
|
|
user => sub {
|
|
my $self = shift;
|
|
return _create_mock('_user',
|
|
roles => sub {
|
|
my $self = shift;
|
|
return $message_role;
|
|
},
|
|
webusername => sub {
|
|
my $self = shift;
|
|
return '$c->user->webusername';
|
|
},
|
|
domain => sub {
|
|
my $self = shift;
|
|
return _create_mock('_domain',
|
|
domain => sub {
|
|
my $self = shift;
|
|
return '$c->user->domain->domain';
|
|
},
|
|
);
|
|
},
|
|
);
|
|
},
|
|
user_exists => sub {
|
|
my $self = shift;
|
|
return 1;
|
|
},
|
|
qs => sub {
|
|
my $self = shift;
|
|
my $str = shift;
|
|
$is_sensitive = 1;
|
|
#return "<<" . $str . ">>" if $str;
|
|
return "\x{ab}" . $str . "\x{bb}" if $str;
|
|
},
|
|
request => sub {
|
|
my $self = shift;
|
|
return _create_mock('_request',
|
|
# _params => {
|
|
# '$c->request->params' => undef,
|
|
# },
|
|
# params => sub {
|
|
# my $self = shift;
|
|
# #return $self->{params}->{$key} if $key;
|
|
# return $self->{params};
|
|
# },
|
|
method => sub {
|
|
my $self = shift;
|
|
return '$c->request->method';
|
|
},
|
|
path => sub {
|
|
my $self = shift;
|
|
return '$c->request->path';
|
|
},
|
|
address => sub {
|
|
my $self = shift;
|
|
return '$c->request->address';
|
|
},
|
|
query_params => sub {
|
|
my $self = shift;
|
|
return { '$c->request->query_params' => undef, };
|
|
},
|
|
parameters => sub {
|
|
my $self = shift;
|
|
return { '$c->request->parameters' => undef, };
|
|
},
|
|
);
|
|
},
|
|
response => sub {
|
|
my $self = shift;
|
|
return _create_mock('_response',
|
|
code => sub {
|
|
my $self = shift;
|
|
return 999; #'$c->response->code';
|
|
},
|
|
);
|
|
},
|
|
_session => {
|
|
api_request_tx_id => '$c->{session}->{api_request_tx_id}',
|
|
},
|
|
session => sub {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
return $self->{session}->{$key} if $key;
|
|
return $self->{session};
|
|
},
|
|
_config => {
|
|
security => {
|
|
log_passwords => 0,
|
|
},
|
|
},
|
|
config => sub {
|
|
my $self = shift;
|
|
#my $key = shift;
|
|
#return $self->{config}->{$key} if $key;
|
|
return $self->{config};
|
|
},
|
|
log => sub {
|
|
my $self = shift;
|
|
return _create_mock('_log',
|
|
error => sub {
|
|
my $self = shift;
|
|
$extracted_message = shift; #global closure needed!
|
|
},
|
|
info => sub {
|
|
my $self = shift;
|
|
$extracted_message = shift; #global closure needed!
|
|
},
|
|
);
|
|
},
|
|
);
|
|
eval {
|
|
no strict "refs"; ## no critic (ProhibitNoStrict)
|
|
"NGCP::Panel::Utils::Message::$method"->(%$args);
|
|
};
|
|
|
|
if ($@) {
|
|
warn($@);
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
sub _deserialize_messagesargs {
|
|
|
|
my $_line = shift;
|
|
my %_params = @_;
|
|
( my $e,
|
|
my $error
|
|
) = @_params{qw/
|
|
e
|
|
error
|
|
/};
|
|
|
|
my $subscriber = _create_mock('subscriber',
|
|
_create_sub_mock('get_inflated_columns'),
|
|
_create_sub_mock('username'),
|
|
_create_sub_mock('uuid'),
|
|
_create_sub_mock('id'),
|
|
contact => sub {
|
|
my $self = shift;
|
|
return _create_mock('contact',_create_sub_mock('email'),);
|
|
},
|
|
domain => sub {
|
|
my $self = shift;
|
|
return _create_mock('domain',_create_sub_mock('domain'),);
|
|
},
|
|
);
|
|
my $contact = _create_mock('contact',
|
|
_create_sub_mock('get_inflated_columns'),
|
|
_create_sub_mock('email'),
|
|
);
|
|
my $contract = _create_mock('contract',
|
|
_create_sub_mock('get_inflated_columns'),
|
|
_create_sub_mock('max_subscribers'),
|
|
_create_sub_mock('id'),
|
|
);
|
|
my $s = $subscriber;
|
|
my $invoice = _create_mock('invoice',
|
|
_create_sub_mock('get_inflated_columns'),
|
|
_create_sub_mock('id'),
|
|
);
|
|
my $pbx_device = _create_mock('pbx_device',
|
|
_create_sub_mock('get_inflated_columns'),
|
|
_create_sub_mock('id'),
|
|
);
|
|
my $c = _create_mock('c',
|
|
_stash => {
|
|
body => '$c->{stash}->{body}',
|
|
hm_rule_result => _create_mock('hm_rule_result',_create_sub_mock('get_inflated_columns'),),
|
|
hm_condition_result => _create_mock('hm_condition_result',_create_sub_mock('get_inflated_columns'),),
|
|
hm_action_result => _create_mock('hm_action_result',_create_sub_mock('get_inflated_columns'),),
|
|
subscriber => $subscriber,
|
|
voicemail => _create_mock('voicemail',_create_sub_mock('get_inflated_columns'),),
|
|
recording => _create_mock('recording',_create_sub_mock('id'),),
|
|
registered => _create_mock('registered',_create_sub_mock('get_inflated_columns'),),
|
|
trusted => _create_mock('trusted',_create_sub_mock('get_inflated_columns'),),
|
|
speeddial => _create_mock('speeddial',_create_sub_mock('get_inflated_columns'),),
|
|
autoattendant => _create_mock('autoattendant',_create_sub_mock('get_inflated_columns'),),
|
|
ccmapping => _create_mock('ccmapping',_create_sub_mock('get_inflated_columns'),),
|
|
body => '$c->{stash}->{number}',
|
|
pattern_result => _create_mock('pattern_result',_create_sub_mock('get_inflated_columns'),), #ncos
|
|
lnp_result => _create_mock('lnp_result',_create_sub_mock('get_inflated_columns'),),
|
|
block => _create_mock('block',_create_sub_mock('get_inflated_columns'),),
|
|
phonebook_result => _create_mock('phonebook_result',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('get_inflated_columns'),),
|
|
devmod => _create_mock('devmod',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('model'),
|
|
_create_sub_mock('vendor'),
|
|
),
|
|
devfw => _create_mock('devfw',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('get_inflated_columns'),),
|
|
devconf => _create_mock('devconf',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('get_inflated_columns'),),
|
|
devprof => _create_mock('devprof',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('get_inflated_columns'),),
|
|
preference_meta => _create_mock('preference_meta',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('attribute'),),
|
|
inv => $invoice,
|
|
sup => _create_mock('sup',_create_sub_mock('get_inflated_columns'),),
|
|
domain_result => _create_mock('domain_result', _create_sub_mock('get_inflated_columns'),),
|
|
set_result => _create_mock('set_result', _create_sub_mock('get_inflated_columns'),),
|
|
rule_result => _create_mock('rule_result', _create_sub_mock('get_inflated_columns'),),
|
|
voucher_result => _create_mock('voucher_result', _create_sub_mock('id'),),
|
|
administrator => _create_mock('administrator',_create_sub_mock('get_inflated_columns'),),
|
|
profile => _create_mock('profile', #profile set
|
|
_id => '$c->{stash}->{profile}->{id}',
|
|
_create_sub_mock('get_inflated_columns'),),
|
|
contract => $contract,
|
|
pbx_device => $pbx_device,
|
|
tmpl => _create_mock('tmpl',_create_sub_mock('get_inflated_columns'),),
|
|
hm_set_result => _create_mock('hm_set_result',_create_sub_mock('get_inflated_columns'),),
|
|
set => _create_mock('set', _create_sub_mock('get_inflated_columns'),), #profile set
|
|
mcid_res => _create_mock('mcid_res', _create_sub_mock('id'),),
|
|
contact => $contact,
|
|
server_result => _create_mock('server_result', _create_sub_mock('get_inflated_columns'),), #peering
|
|
rule_result => _create_mock('rule_result', _create_sub_mock('get_inflated_columns'),), #peering
|
|
group_result => _create_mock('group_result', _create_sub_mock('get_inflated_columns'),), #peering
|
|
inbound_rule_result => _create_mock('inbound_rule_result', _create_sub_mock('get_inflated_columns'),), #peering
|
|
file_result => _create_mock('file_result', _create_sub_mock('get_inflated_columns'),),
|
|
},
|
|
stash => sub {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
return $self->{stash}->{$key} if $key;
|
|
return $self->{stash};
|
|
},
|
|
loc => sub {
|
|
my $self = shift;
|
|
my $str = shift;
|
|
my @params = @_;
|
|
for (my $i = 1; $i <= scalar @params; $i++) {
|
|
my $subst = quotemeta("[_$i]");
|
|
my $repl = $params[$i - 1];
|
|
$str =~ s/$subst/$repl/g;
|
|
}
|
|
return $str;
|
|
},
|
|
qs => sub {
|
|
my $self = shift;
|
|
my $str = shift;
|
|
$is_sensitive = 1;
|
|
#return "<<" . $str . ">>" if $str;
|
|
return "\x{ab}" . $str . "\x{bb}" if $str;
|
|
},
|
|
user => sub {
|
|
my $self = shift;
|
|
return _create_mock('user',
|
|
_create_sub_mock('id'),
|
|
_create_sub_mock('account_id'),
|
|
_create_sub_mock('uuid'),);
|
|
},
|
|
request => sub {
|
|
my $self = shift;
|
|
return _create_mock('request',
|
|
_params => {
|
|
'$c->request->params' => undef,
|
|
},
|
|
params => sub {
|
|
my $self = shift;
|
|
#return $self->{params}->{$key} if $key;
|
|
return $self->{params};
|
|
},
|
|
);
|
|
},
|
|
);
|
|
#my $e = '$e';
|
|
my $msg = '$msg';
|
|
my $vars = {
|
|
invoice => '$vars->{invoice}',
|
|
};
|
|
#my $error = _create_mock('error',
|
|
# _error => '$error->{error}',
|
|
# _description => '$error->{description}',
|
|
# _create_sub_mock('type'),
|
|
# _create_sub_mock('info'),
|
|
#);
|
|
my %log_data = ('%log_data' => undef, );
|
|
my $text = \'$text';
|
|
my $text_success = \'$text_success';
|
|
my $response_body = '$response_body';
|
|
my $params_data = '$params_data';
|
|
my $attribute = '$attribute';
|
|
my $subscriber_id = '$subscriber_id';
|
|
my $set = _create_mock('set', _create_sub_mock('get_inflated_columns'),);
|
|
my $pref_id = '$pref_id';
|
|
my $cf_type = '$cf_type';
|
|
my $type = '$type'; #voicemail greeting type
|
|
my $vm_id = '$vm_id';
|
|
my $rec_id = '$rec_id';
|
|
my $stream_id = '$stream_id';
|
|
my $data = '$data';
|
|
my $reg_id = '$reg_id';
|
|
my $trusted_id = '$trusted_id';
|
|
my $rws_id = '$rws_id';
|
|
my $sd_id = '$sd_id';
|
|
my $aa_id = '$aa_id';
|
|
my $phonebook_id = '$phonebook_id';
|
|
my $carrier_id = '$carrier_id';
|
|
my $number_id = '$number_id'; #lnp
|
|
my $form = _create_mock('form',
|
|
_values => {
|
|
lnp_provider_id => '$form->{values}->{lnp_provider_id}',
|
|
name => '$form->{values}->{name}',
|
|
emergency_container_id => '$form->{values}->{emergency_container_id}',
|
|
code => '$form->{values}->{code}',
|
|
},
|
|
values => sub {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
return $self->{values}->{$key} if $key;
|
|
return $self->{values};
|
|
},
|
|
);
|
|
my $ip = '$ip'; #banned
|
|
my $user = '$user'; #banned
|
|
my $contract_id = '$contract_id';
|
|
my $devmod_id = '$devmod_id';
|
|
my $devfw_id = '$devfw_id';
|
|
my $devconf_id = '$devconf_id';
|
|
my $devprof_id = '$devprof_id';
|
|
my $emergency_container_id = '$emergency_container_id';
|
|
my $emergency_mapping_id = '$emergency_mapping_id';
|
|
my $reseller_id = '$reseller_id';
|
|
my $domain_id = '$domain_id';
|
|
my $network_id = '$network_id';
|
|
my $voucher_id = '$voucher_id';
|
|
my $administrator_id = '$administrator_id';
|
|
my $message = '$message';
|
|
my $special_user_login = '$special_user_login';
|
|
my $result = '$result'; #certificate
|
|
my $reseller = _create_mock('reseller', _create_sub_mock('get_inflated_columns'),);
|
|
my %defaults = (
|
|
admins => {
|
|
login => '$defaults{admins}->{login}',
|
|
},
|
|
);
|
|
my $default_pass = '$default_pass';
|
|
my $timeset_id = '$timeset_id';
|
|
my $package_id = '$package_id';
|
|
my $profile_id = '$profile_id';
|
|
my $fee_id = '$fee_id';
|
|
my $zone_id = '$zone_id';
|
|
my $zone_info = '$zone_info';
|
|
my $weekday_id = '$weekday_id';
|
|
my $rs = _create_mock('rs', _create_sub_mock('get_inflated_columns'),); #timerange rs
|
|
my $special_id = '$special_id';
|
|
my $special_result_info = '$special_result_info';
|
|
my $product = '$product';
|
|
my $uri = '$uri';
|
|
my $fraud_prefs = _create_mock('fraud_prefs', _create_sub_mock('get_inflated_columns'),);
|
|
my $group_id = '$group_id'; #pbx group id
|
|
my $dev_id = '$dev_id';
|
|
my $line = _create_mock('line',
|
|
field => sub {
|
|
my $self = shift;
|
|
my $field = shift;
|
|
return _create_mock('field',
|
|
_create_sub_mock('value'),);
|
|
},
|
|
);
|
|
my %hm_rule_columns = ('%hm_rule_columns' => undef);
|
|
my @out = ('@out');
|
|
my $location_id = '$location_id';
|
|
my $contact_id = '$contact_id';
|
|
my $group_name = '$group_name'; #app server
|
|
use Data::Dumper;
|
|
my $args = eval $_line;
|
|
if ($@) {
|
|
warn($_line ."\n" .$@);
|
|
return undef;
|
|
} else {
|
|
return $args;
|
|
}
|
|
|
|
}
|
|
|
|
sub _create_sub_mock {
|
|
my $subname = shift;
|
|
return ($subname,sub {
|
|
my $self = shift;
|
|
return '$' . (ref $self) . '->' . $subname; # . '()'; #(caller(0))[3];
|
|
});
|
|
}
|
|
|
|
sub _create_mock {
|
|
my $class = shift;
|
|
return $mock_objs{$class} if exists $mock_objs{$class};
|
|
my %members = @_;
|
|
my $obj = bless({},$class);
|
|
foreach my $member (keys %members) {
|
|
if ('CODE' eq ref $members{$member}) {
|
|
no strict "refs"; ## no critic (ProhibitNoStrict)
|
|
*{$class.'::'.$member} = $members{$member};
|
|
} else {
|
|
$obj->{substr($member,1)} = $members{$member};
|
|
}
|
|
}
|
|
$mock_objs{$class} = $obj;
|
|
return $obj;
|
|
}
|
|
|
|
#foreach my $x (_generate_combinations([qw(1 2 3)], [qw(a b)], [qw(C D)])) {
|
|
# print join("-",@$x)."\n";
|
|
#}
|
|
|
|
sub _generate_combinations {
|
|
my @arrays = grep @$_, @_;
|
|
my $min = @arrays;
|
|
my @current = ([]);
|
|
for my $array (@arrays) {
|
|
$min++;
|
|
@current = map {
|
|
my $n = $_;
|
|
my @res = map { my $r = [@$n]; push(@$r,$_); $r; } @$array;
|
|
unless (scalar @$n < $min) {
|
|
unshift(@res,$n);
|
|
}
|
|
@res;
|
|
} @current;
|
|
}
|
|
return @current;
|
|
}
|
|
|
|
sub _get_source_file_name {
|
|
my ($inputfilename,$inputfiledir,$inputfilesuffix) = @_;
|
|
my @dirparts = File::Spec->splitdir($inputfiledir);
|
|
return $dirparts[$#dirparts - 1] . '/' . $inputfilename.$inputfilesuffix;
|
|
}
|
|
|
|
sub _list_variables {
|
|
my $log_line = shift;
|
|
|
|
my @variables = ();
|
|
#while ($log_line->{log_line} =~ /(\$[^\s:.)'"]+)/gm) {
|
|
while ($log_line->{log_line} =~ /(\$[\$a-zA-Z0-9_>{}-]+)/gm) {
|
|
my $var = $1;
|
|
push(@variables,{
|
|
variable => $var,
|
|
description => '#todo',
|
|
});
|
|
#print $var . "\n" unless exists $distinct_variables{$var};
|
|
$distinct_variables{$var} = 0 unless exists $distinct_variables{$var};
|
|
$distinct_variables{$var} += 1;
|
|
}
|
|
$log_line->{variables} = \@variables if scalar @variables > 0;
|
|
|
|
return $log_line;
|
|
}
|
|
|
|
sub _dispatch_logfile {
|
|
|
|
my $log_line = shift;
|
|
# see rsyslog.conf:
|
|
#if $programname == 'ngcp-panel' and $msg startswith ' DEBUG' then {
|
|
# -/var/log/ngcp/panel-debug.log
|
|
# stop
|
|
#}
|
|
#
|
|
#if $programname == 'ngcp-panel' and $msg contains 'CALLED=API' then {
|
|
# -/var/log/ngcp/api.log
|
|
# stop
|
|
#}
|
|
#
|
|
#:programname, isequal, "ngcp-panel" {
|
|
# -/var/log/ngcp/panel.log
|
|
# stop
|
|
#}
|
|
if ($log_line->{level} eq 'debug') {
|
|
push(@{$result{'panel-debug.log'}},$log_line);
|
|
} elsif (index($log_line->{log_line},'CALLED=API') >= 0) {
|
|
push(@{$result{'api.log'}},$log_line);
|
|
#print $log_line->{log_line} . "\n";
|
|
} else {
|
|
push(@{$result{'panel.log'}},$log_line);
|
|
#print $log_line->{log_line} . "\n";
|
|
}
|
|
|
|
}
|
|
|
|
sub write_ymls {
|
|
print "log inventory .yml output:\n";
|
|
foreach my $logfile (keys %result) {
|
|
my ($filename,$dir,$suffix) = File::Basename::fileparse($logfile, '.log');
|
|
my $output_filename = $filename.'.yml';
|
|
unlink $output_filename;
|
|
YAML::XS::DumpFile($output_filename, {
|
|
blacklist_pattern => '#todo',
|
|
date => _datestamp(),
|
|
gdpr_status => {
|
|
0 => 'not affected',
|
|
1 => 'potentially affected',
|
|
2 => 'affected',
|
|
},
|
|
log_file => {
|
|
description => $filename . $suffix . ' file generated by ngcp admin -panel and rest-api',
|
|
gdpr_status => 2,
|
|
log_lines => $result{$logfile},
|
|
}
|
|
});
|
|
print " $output_filename: " . scalar @{$result{$logfile}} . " messages\n";
|
|
}
|
|
}
|
|
|
|
sub _datestamp {
|
|
|
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
|
return sprintf "%4d-%02d-%02d",$year+1900,$mon+1,$mday;
|
|
|
|
} |