From efe17f842247d4b7f3464dce23cdea729812c19e Mon Sep 17 00:00:00 2001 From: Rene Krenn Date: Wed, 15 Oct 2025 22:26:11 +0200 Subject: [PATCH] MT#63759 prov templates: parse .csv header to process .csv files created via excel "save as" -> "CSV UTF-8" directly, the header is now analyzed by Text::CSV_XS. this will automagically determine utf BOM and separator char. furthermore, some fixes are added for provisionion templates base on JavaScript, after adding a trim() method for strings. caching of domains (+resellers, billing_profiles, profile_packages is now fixed to propery print "unknown domain ..." for each line. furthermore, the ngcp-provisioning_template script is fixed to work again after changes: MT#60558 invoke max subscribers/group license check only on POST MT#59078 ?create_primary_acli= query param Change-Id: I8b53ab1c6071de27c62d29e921634063a725c130 (cherry picked from commit 2460c6e3d8a98203331410fddc3f22484720f7ae) (cherry picked from commit d222f77f1f349fe11a188d785812ae3efed7c304) --- lib/NGCP/Panel/Utils/ProvisioningTemplates.pm | 56 ++++++++++++------- tools_bin/ngcp-provisioning-template | 10 ++++ 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/lib/NGCP/Panel/Utils/ProvisioningTemplates.pm b/lib/NGCP/Panel/Utils/ProvisioningTemplates.pm index 35557ed821..397a3dadf7 100644 --- a/lib/NGCP/Panel/Utils/ProvisioningTemplates.pm +++ b/lib/NGCP/Panel/Utils/ProvisioningTemplates.pm @@ -307,7 +307,7 @@ sub process_csv { my $csv = Text::CSV_XS->new({ allow_whitespace => 1, binary => 1, - keep_meta_info => 1 + keep_meta_info => 1, }); my $fields = get_fields($c,0); my @cols = keys %$fields; @@ -318,15 +318,19 @@ sub process_csv { purge => $purge, ); open(my $fh, '<:encoding(utf8)', $data); - while ( my $line = <$fh> ){ + binmode $fh; + $csv->header($fh); + while (my $row = $csv->getline_hr($fh)) { + #while ( my $line = <$fh> ){ ++$linenum; - next unless length $line; - unless($csv->parse($line)) { - push(@fails,{ linenum => $linenum, }); - next; - } - my $row = {}; - @{$row}{keys %$fields} = $csv->fields(); + #next unless length $line; + #unless($csv->parse($line)) { + # push(@fails,{ linenum => $linenum, }); + # next; + #} + #my $row = {}; + #@{$row}{keys %$fields} = $csv->fields(); + #my $row = try { provision_commit_row( c => $c, @@ -441,7 +445,7 @@ sub provision_begin { foreach my $sub (qw(debug info warn error)) { $subs{$sub} = sub { - return $c->log->$sub(( map { ($_ // '') . ''; } @_)); + return $c->log->$sub(( map { _unbox_je_value($_); } @_)); }; } @@ -470,9 +474,11 @@ sub provision_begin { $string =~ s/^\s+|\s+$//g; return $string; }; + $subs{'die'} = sub { return die(( map { _unbox_je_value($_); } @_)); }; + while (each %subs) { $context->{_je}->new_function($_ => $subs{$_}); } @@ -779,8 +785,8 @@ sub _init_contract_context { } if (exists $contract_contact{reseller}) { $context->{_r_c} //= {}; - if (exists $context->{_r_c}->{$contract_contact{reseller}} - or ($context->{_r_c}->{$contract_contact{reseller}} = $schema->resultset('resellers')->search_rs({ + if ($context->{_r_c}->{$contract_contact{reseller}} + or (not exists $context->{_r_c}->{$contract_contact{reseller}} and $context->{_r_c}->{$contract_contact{reseller}} = $schema->resultset('resellers')->search_rs({ name => $contract_contact{reseller}, status => { '!=' => 'terminated' }, })->first)) { @@ -824,8 +830,8 @@ sub _init_contract_context { } if (exists $contract{profile_package}) { $context->{_pp_c} //= {}; - if (exists $context->{_pp_c}->{$contract{profile_package}} - or ($context->{_pp_c}->{$contract{profile_package}} = $schema->resultset('profile_packages')->search_rs({ + if ($context->{_pp_c}->{$contract{profile_package}} + or (not exists $context->{_pp_c}->{$contract{profile_package}} and $context->{_pp_c}->{$contract{profile_package}} = $schema->resultset('profile_packages')->search_rs({ name => $contract{profile_package}, #reseller_id #status => { '!=' => 'terminated' }, @@ -839,8 +845,8 @@ sub _init_contract_context { } if (exists $contract{billing_profile}) { $context->{_bp_c} //= {}; - if (exists $context->{_bp_c}->{$contract{billing_profile}} - or ($context->{_bp_c}->{$contract{billing_profile}} = $schema->resultset('billing_profiles')->search_rs({ + if ($context->{_bp_c}->{$contract{billing_profile}} + or (not exists $context->{_bp_c}->{$contract{billing_profile}} and $context->{_bp_c}->{$contract{billing_profile}} = $schema->resultset('billing_profiles')->search_rs({ name => $contract{billing_profile}, #todo: reseller_id status => { '!=' => 'terminated' }, @@ -854,8 +860,8 @@ sub _init_contract_context { } if (exists $contract{product}) { $context->{_pr_c} //= {}; - if (exists $context->{_pr_c}->{$contract{product}} - or ($context->{_pr_c}->{$contract{product}} = $schema->resultset('products')->search_rs({ + if ($context->{_pr_c}->{$contract{product}} + or (not exists $context->{_pr_c}->{$contract{product}} and $context->{_pr_c}->{$contract{product}} = $schema->resultset('products')->search_rs({ name => $contract{product}, })->first)) { $contract{product_id} = $context->{_pr_c}->{$contract{product}}->id; @@ -918,8 +924,8 @@ sub _init_subscriber_context { } if (exists $subscriber{domain}) { $context->{_bd_c} //= {}; - if (exists $context->{_bd_c}->{$subscriber{domain}} - or ($context->{_bd_c}->{$subscriber{domain}} = $schema->resultset('domains')->search_rs({ + if ($context->{_bd_c}->{$subscriber{domain}} + or (not exists $context->{_bd_c}->{$subscriber{domain}} and $context->{_bd_c}->{$subscriber{domain}} = $schema->resultset('domains')->search_rs({ domain => $subscriber{domain}, #todo: reseller_id #status => { '!=' => 'terminated' }, @@ -1479,8 +1485,16 @@ sub _unbox_je_value { my $v = shift; return unless defined $v; - if ((ref $v) =~ /^JE::/) { + if ((ref $v) =~ /^JE::Object/) { $v = $v->value; + } elsif ((ref $v) =~ /^JE::String/) { + $v = $v . ''; + } elsif ((ref $v) =~ /^JE::Number/) { + $v = $v + 0; + } elsif ((ref $v) =~ /^JE::Boolean/) { + $v = ($v ? 1 : 0); + } elsif ((ref $v) =~ /^JE::(Null|Undefined)/) { + $v = undef; } elsif ($JE_ANON_CLASS eq ref $v) { $v = _unbless($v); } diff --git a/tools_bin/ngcp-provisioning-template b/tools_bin/ngcp-provisioning-template index ae06eca6ab..158beccc09 100755 --- a/tools_bin/ngcp-provisioning-template +++ b/tools_bin/ngcp-provisioning-template @@ -184,10 +184,20 @@ sub _create_c { return $self->{param}->{$key} if $key; return $self->{param}; }, + params => sub { + my $self = shift; + my $key = shift; + return $self->{param}->{$key} if $key; + return $self->{param}; + }, path => sub { my $self = shift; return 'api/'; }, + method => sub { + my $self = shift; + return ''; #disable license checks (max_subscribers) for now + }, ); };