blob: ffc7713c308af01c5e6f87c98c557bac9453d166 [file] [log] [blame]
package UI::ConfigFiles;
#
# Copyright 2015 Comcast Cable Communications Management, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
#
use UI::Utils;
use Mojo::Base 'Mojolicious::Controller';
use Data::Dumper;
use Date::Manip;
use NetAddr::IP;
use UI::DeliveryService;
use JSON;
use API::DeliveryService::KeysUrlSig qw(URL_SIG_KEYS_BUCKET);
my $dispatch_table ||= {
"logs_xml.config" => sub { logs_xml_dot_config(@_) },
"cacheurl.config" => sub { cacheurl_dot_config(@_) },
"records.config" => sub { generic_config(@_) },
"plugin.config" => sub { generic_config(@_) },
"astats.config" => sub { generic_config(@_) },
"volume.config" => sub { volume_dot_config(@_) },
"hosting.config" => sub { hosting_dot_config(@_) },
"storage.config" => sub { storage_dot_config(@_) },
"50-ats.rules" => sub { ats_dot_rules(@_) },
"cache.config" => sub { cache_dot_config(@_) },
"remap.config" => sub { remap_dot_config(@_) },
"parent.config" => sub { parent_dot_config(@_) },
"sysctl.conf" => sub { generic_config(@_) },
"ip_allow.config" => sub { ip_allow_dot_config(@_) },
"12M_facts" => sub { facts(@_) },
"regex_revalidate.config" => sub { regex_revalidate_dot_config(@_) },
"drop_qstring.config" => sub { drop_qstring_dot_config(@_) },
"bg_fetch.config" => sub { bg_fetch_dot_config(@_) },
"url_sig_.config" => sub { url_sig_config(@_) },
"hdr_rw_.config" => sub { header_rewrite_dot_config(@_) },
"set_dscp_.config" => sub { header_rewrite_dscp_dot_config(@_) },
"to_ext_.config" => sub { to_ext_dot_config(@_) },
"regex_remap_.config" => sub { regex_remap_dot_config(@_) },
"cacheurl_.config" => sub { cacheurl_dot_config(@_) },
"all" => sub { gen_fancybox_data(@_) },
"ssl_multicert.config" => sub { ssl_multicert_dot_config(@_) },
};
my $separator ||= {
"records.config" => " ",
"plugin.config" => " ",
"sysctl.conf" => " = ",
"url_sig_.config" => " = ",
"astats.config" => "=",
};
sub genfiles {
my $self = shift;
my $mode = $self->param('mode');
my $id = $self->param('id');
my $file = $self->param('filename');
my $org_name = $file;
$file =~ s/^url_sig_.*\.config$/url_sig_\.config/;
$file =~ s/^hdr_rw_.*\.config$/hdr_rw_\.config/;
$file =~ s/^set_dscp_.*\.config$/set_dscp_\.config/;
$file =~ s/^regex_remap_.*\.config$/regex_remap_\.config/;
$file =~ s/^cacheurl_.*\.config$/cacheurl_\.config/;
$file =~ s/^to_ext_.*\.config$/to_ext_\.config/;
my $text = undef;
if ( $mode eq 'view' ) {
if ( defined( $dispatch_table->{$file} ) ) {
$text = $dispatch_table->{$file}->( $self, $id, $org_name );
}
else {
$text = &take_and_bake( $self, $id, $org_name );
}
}
if ( $text =~ /^Error/ ) {
$self->internal_server_error( { Error => $text } );
}
if ( $file ne "all" ) {
$self->res->headers->content_type("application/download");
$self->res->headers->content_disposition("attachment; filename=\"$org_name\"");
$self->render( text => $text, format => 'txt' );
}
else {
# ignore $text, the good stuff is in the stash
$self->stash( fbox_layout => 1 );
}
}
sub gen_fancybox_data {
my $self = shift;
my $id = shift;
my $filename = shift;
my $file_text;
my $server = $self->server_data($id);
my $ds_data = $self->ds_data($server);
my $rs = $self->db->resultset('ProfileParameter')->search(
{ -and => [ profile => $server->profile->id, 'parameter.name' => 'location' ] },
{ prefetch => [ { parameter => undef }, { profile => undef } ] }
);
while ( my $row = $rs->next ) {
my $file = $row->parameter->config_file;
# print "Genning $file\n";
my $org_name = $file;
$file =~ s/^url_sig_.*\.config$/url_sig_\.config/;
$file =~ s/^hdr_rw_.*\.config$/hdr_rw_\.config/;
$file =~ s/^set_dscp_.*\.config$/set_dscp_\.config/;
$file =~ s/^regex_remap_.*\.config$/regex_remap_\.config/;
$file =~ s/^cacheurl_.*\.config$/cacheurl_\.config/;
$file =~ s/^to_ext_.*\.config$/to_ext_\.config/;
my $text = "boo";
if ( defined( $dispatch_table->{$file} ) ) {
$text = $dispatch_table->{$file}->( $self, $id, $org_name, $ds_data );
}
else {
$text = &take_and_bake( $self, $id, $org_name, $ds_data );
}
$file_text->{$org_name} = $text;
}
$self->stash( file_text => $file_text );
$self->stash( host_name => $server->host_name );
}
sub server_data {
my $self = shift;
my $id = shift;
my $server;
# if ( defined( $self->app->session->{server_data} ) ) {
# $server = $self->app->session->{server_data};
# return $server;
# }
if ( $id =~ /^\d+$/ ) {
$server = $self->db->resultset('Server')->search( { id => $id } )->single;
}
else {
$server = $self->db->resultset('Server')->search( { host_name => $id } )->single;
}
# $self->app->session->{server_data} = $server;
return $server;
}
sub header_comment {
my $self = shift;
my $host_name = shift;
my $text = "# DO NOT EDIT - Generated for " . $host_name . " by " . &name_version_string($self) . " on " . `date`;
return $text;
}
sub ds_data {
my $self = shift;
my $server = shift;
my $dsinfo;
# if ( defined( $self->app->session->{dsinfo} ) ) {
# $dsinfo = $self->app->session->{dsinfo};
# return $dsinfo;
# }
$dsinfo->{host_name} = $server->host_name;
$dsinfo->{domain_name} = $server->domain_name;
my @server_ids = ();
my $rs;
if ( $server->type->name =~ m/^MID/ ) {
# the mids will do all deliveryservices in this CDN
my $domain = $self->profile_param_value( $server->profile->id, 'CRConfig.json', 'domain_name', '' );
$rs = $self->db->resultset('DeliveryServiceInfoForDomainList')->search( {}, { bind => [$domain] } );
}
else {
$rs = $self->db->resultset('DeliveryServiceInfoForServerList')->search( {}, { bind => [ $server->id ] } );
}
my $j = 0;
while ( my $row = $rs->next ) {
my $org_server = $row->org_server_fqdn;
my $dscp = $row->dscp;
my $re_type = $row->re_type;
my $ds_type = $row->ds_type;
my $signed = $row->signed;
my $qstring_ignore = $row->qstring_ignore;
my $ds_xml_id = $row->xml_id;
my $ds_domain = $row->domain_name;
my $edge_header_rewrite = $row->edge_header_rewrite;
my $mid_header_rewrite = $row->mid_header_rewrite;
my $regex_remap = $row->regex_remap;
my $protocol = $row->protocol;
my $range_request_handling = $row->range_request_handling;
my $origin_shield = $row->origin_shield;
my $cacheurl = $row->cacheurl;
my $remap_text = $row->remap_text;
my $multi_site_origin = $row->multi_site_origin;
my $multi_site_origin_algorithm = $row->multi_site_origin_algorithm;
if ( $re_type eq 'HOST_REGEXP' ) {
my $host_re = $row->pattern;
my $map_to = $org_server . "/";
if ( $host_re =~ /\.\*$/ ) {
my $re = $host_re;
$re =~ s/\\//g;
$re =~ s/\.\*//g;
my $hname = $ds_type =~ /^DNS/ ? "edge" : "ccr";
my $portstr = "";
if ( $hname eq "ccr" && $server->tcp_port > 0 && $server->tcp_port != 80 ) {
$portstr = ":" . $server->tcp_port;
}
my $map_from = "http://" . $hname . $re . $ds_domain . $portstr . "/";
if ( $protocol == 0 ) {
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
}
elsif ( $protocol == 1 ) {
$map_from = "https://" . $hname . $re . $ds_domain . "/";
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
}
elsif ( $protocol == 2 ) {
#add the first one with http
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
#add the second one for https
my $map_from2 = "https://" . $hname . $re . $ds_domain . "/";
$dsinfo->{dslist}->[$j]->{"remap_line2"}->{$map_from2} = $map_to;
}
}
else {
my $map_from = "http://" . $host_re . "/";
if ( $protocol == 0 ) {
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
}
elsif ( $protocol == 1 ) {
$map_from = "https://" . $host_re . "/";
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
}
elsif ( $protocol == 2 ) {
#add the first with http
$dsinfo->{dslist}->[$j]->{"remap_line"}->{$map_from} = $map_to;
#add the second with https
my $map_from2 = "https://" . $host_re . "/";
$dsinfo->{dslist}->[$j]->{"remap_line2"}->{$map_from2} = $map_to;
}
}
}
$dsinfo->{dslist}->[$j]->{"dscp"} = $dscp;
$dsinfo->{dslist}->[$j]->{"org"} = $org_server;
$dsinfo->{dslist}->[$j]->{"type"} = $ds_type;
$dsinfo->{dslist}->[$j]->{"domain"} = $ds_domain;
$dsinfo->{dslist}->[$j]->{"signed"} = $signed;
$dsinfo->{dslist}->[$j]->{"qstring_ignore"} = $qstring_ignore;
$dsinfo->{dslist}->[$j]->{"ds_xml_id"} = $ds_xml_id;
$dsinfo->{dslist}->[$j]->{"edge_header_rewrite"} = $edge_header_rewrite;
$dsinfo->{dslist}->[$j]->{"mid_header_rewrite"} = $mid_header_rewrite;
$dsinfo->{dslist}->[$j]->{"regex_remap"} = $regex_remap;
$dsinfo->{dslist}->[$j]->{"range_request_handling"} = $range_request_handling;
$dsinfo->{dslist}->[$j]->{"origin_shield"} = $origin_shield;
$dsinfo->{dslist}->[$j]->{"cacheurl"} = $cacheurl;
$dsinfo->{dslist}->[$j]->{"remap_text"} = $remap_text;
$dsinfo->{dslist}->[$j]->{"multi_site_origin"} = $multi_site_origin;
$dsinfo->{dslist}->[$j]->{"multi_site_origin_algorithm"} = $multi_site_origin_algorithm;
if ( defined($edge_header_rewrite) ) {
my $fname = "hdr_rw_" . $ds_xml_id . ".config";
$dsinfo->{dslist}->[$j]->{"hdr_rw_file"} = $fname;
}
if ( defined($mid_header_rewrite) ) {
my $fname = "hdr_rw_mid_" . $ds_xml_id . ".config";
$dsinfo->{dslist}->[$j]->{"mid_hdr_rw_file"} = $fname;
}
if ( defined($cacheurl) ) {
my $fname = "cacheurl_" . $ds_xml_id . ".config";
$dsinfo->{dslist}->[$j]->{"cacheurl_file"} = $fname;
}
$j++;
}
# $self->app->session->{dsinfo} = $dsinfo;
return $dsinfo;
}
sub param_data {
my $self = shift;
my $server = shift;
my $filename = shift;
my $data;
my $rs = $self->db->resultset('ProfileParameter')->search( { -and => [ profile => $server->profile->id, 'parameter.config_file' => $filename ] },
{ prefetch => [ { parameter => undef }, { profile => undef } ] } );
while ( my $row = $rs->next ) {
if ( $row->parameter->name eq "location" ) {
next;
}
my $value = $row->parameter->value;
# some files have multiple lines with the same key... handle that with param id.
my $key = $row->parameter->name;
if ( defined( $data->{$key} ) ) {
$key .= "__" . $row->parameter->id;
}
if ( $value =~ /^STRING __HOSTNAME__$/ ) {
$value = "STRING " . $server->host_name . "." . $server->domain_name;
}
$data->{$key} = $value;
}
return $data;
}
sub profile_param_value {
my $self = shift;
my $pid = shift;
my $file = shift;
my $param_name = shift;
my $default = shift;
# assign $ds_domain, $weight and $port, and cache the results %profile_cache
my $param =
$self->db->resultset('ProfileParameter')
->search( { -and => [ profile => $pid, 'parameter.config_file' => $file, 'parameter.name' => $param_name ] },
{ prefetch => [ 'parameter', 'profile' ] } )->single();
return ( defined $param ? $param->parameter->value : $default );
}
sub by_parent_rank {
my ($arank) = $a->{"rank"};
my ($brank) = $b->{"rank"};
( $arank || 1 ) <=> ( $brank || 1 );
}
sub parent_data {
my $self = shift;
my $server = shift;
my @parent_cachegroup_ids;
my @secondary_parent_cachegroup_ids;
my $org_loc_type_id = &type_id( $self, "ORG_LOC" );
if ( $server->type->name =~ m/^MID/ ) {
# multisite origins take all the org groups in to account
@parent_cachegroup_ids = $self->db->resultset('Cachegroup')->search( { type => $org_loc_type_id } )->get_column('id')->all();
}
else {
@parent_cachegroup_ids =
grep {defined} $self->db->resultset('Cachegroup')->search( { id => $server->cachegroup->id } )->get_column('parent_cachegroup_id')->all();
@secondary_parent_cachegroup_ids =
grep {defined}
$self->db->resultset('Cachegroup')->search( { id => $server->cachegroup->id } )->get_column('secondary_parent_cachegroup_id')->all();
}
# get the server's cdn domain
my $server_domain = $self->profile_param_value( $server->profile->id, 'CRConfig.json', 'domain_name' );
my %profile_cache;
my %deliveryservices;
my %parent_info;
$self->cachegroup_profiles( \@parent_cachegroup_ids, \%profile_cache, \%deliveryservices );
$self->cachegroup_profiles( \@secondary_parent_cachegroup_ids, \%profile_cache, \%deliveryservices );
foreach my $prefix ( keys %deliveryservices ) {
foreach my $row ( @{ $deliveryservices{$prefix} } ) {
my $pid = $row->profile->id;
my $ds_domain = $profile_cache{$pid}->{domain_name};
my $weight = $profile_cache{$pid}->{weight};
my $port = $profile_cache{$pid}->{port};
my $use_ip_address = $profile_cache{$pid}->{use_ip_address};
my $rank = $profile_cache{$pid}->{rank};
my $parent = $server->cachegroup->parent_cachegroup_id // -1;
my $secondary = $server->cachegroup->secondary_parent_cachegroup_id // -1;
if ( defined($ds_domain) && defined($server_domain) && $ds_domain eq $server_domain ) {
my %p = (
host_name => $row->host_name,
port => defined($port) ? $port : $row->tcp_port,
domain_name => $row->domain_name,
weight => $weight,
use_ip_address => $use_ip_address,
rank => $rank,
ip_address => $row->ip_address,
parent => ( $parent == $row->cachegroup->id ) ? 1 : 0,
secondary => ( $secondary == $row->cachegroup->id ) ? 1 : 0,
);
push @{ $parent_info{$prefix} }, \%p;
}
}
}
return \%parent_info;
}
sub cachegroup_profiles {
my $self = shift;
my $ids = shift;
my $profile_cache = shift;
my $deliveryservices = shift;
if ( !@$ids ) {
return; # nothing to see here..
}
my $online = &admin_status_id( $self, "ONLINE" );
my $reported = &admin_status_id( $self, "REPORTED" );
my %condition = (
status => { -in => [ $online, $reported ] },
cachegroup => { -in => $ids }
);
my $rs_parent = $self->db->resultset('Server')->search( \%condition, { prefetch => [ 'cachegroup', 'status', 'type', 'profile' ] } );
while ( my $row = $rs_parent->next ) {
next unless ( $row->type->name eq 'ORG' || $row->type->name =~ m/^EDGE/ || $row->type->name =~ m/^MID/ );
if ( $row->type->name eq 'ORG' ) {
my $rs_ds = $self->db->resultset('DeliveryserviceServer')->search( { server => $row->id }, { prefetch => ['deliveryservice'] } );
while ( my $ds_row = $rs_ds->next ) {
my $ds_domain = $ds_row->deliveryservice->org_server_fqdn;
$ds_domain =~ s/https?:\/\/(.*)/$1/;
push( @{ $deliveryservices->{$ds_domain} }, $row );
}
}
else {
push( @{ $deliveryservices->{all_parents} }, $row );
}
# get the profile info, and cache it in %profile_cache
my $pid = $row->profile->id;
if ( !defined( $profile_cache->{$pid} ) ) {
# assign $ds_domain, $weight and $port, and cache the results %profile_cache
$profile_cache->{$pid} = {
domain_name => $self->profile_param_value( $pid, 'CRConfig.json', 'domain_name', undef ),
weight => $self->profile_param_value( $pid, 'parent.config', 'weight', '0.999' ),
port => $self->profile_param_value( $pid, 'parent.config', 'port', undef ),
use_ip_address => $self->profile_param_value( $pid, 'parent.config', 'use_ip_address', 0 ),
rank => $self->profile_param_value( $pid, 'parent.config', 'rank', 1 ),
};
}
}
}
sub ip_allow_data {
my $self = shift;
my $server = shift;
my $ipallow;
$ipallow = ();
my $i = 0;
# localhost is trusted.
$ipallow->[$i]->{src_ip} = '127.0.0.1';
$ipallow->[$i]->{action} = 'ip_allow';
$ipallow->[$i]->{method} = "ALL";
$i++;
$ipallow->[$i]->{src_ip} = '::1';
$ipallow->[$i]->{action} = 'ip_allow';
$ipallow->[$i]->{method} = "ALL";
$i++;
my $rs_parameter =
$self->db->resultset('ProfileParameter')
->search( { profile => $server->profile->id }, { prefetch => [ { parameter => undef }, { profile => undef } ] } );
while ( my $row = $rs_parameter->next ) {
if ( $row->parameter->name eq 'purge_allow_ip' && $row->parameter->config_file eq 'ip_allow.config' ) {
$ipallow->[$i]->{src_ip} = $row->parameter->value;
$ipallow->[$i]->{action} = "ip_allow";
$ipallow->[$i]->{method} = "ALL";
$i++;
}
}
if ( $server->type->name =~ m/^MID/ ) {
my @edge_locs = $self->db->resultset('Cachegroup')->search( { parent_cachegroup_id => $server->cachegroup->id } )->get_column('id')->all();
my %allow_locs;
foreach my $loc (@edge_locs) {
$allow_locs{$loc} = 1;
}
# get all the EDGE and RASCAL nets
my @allowed_netaddrips;
my @allowed_ipv6_netaddrips;
my @types;
push( @types, &type_ids( $self, 'EDGE%', 'server' ) );
my $rtype = &type_id( $self, 'RASCAL' );
push( @types, $rtype );
my $rs_allowed = $self->db->resultset('Server')->search( { 'me.type' => { -in => \@types } }, { prefetch => [ 'type', 'cachegroup' ] } );
while ( my $allow_row = $rs_allowed->next ) {
if ( $allow_row->type->id == $rtype
|| ( defined( $allow_locs{ $allow_row->cachegroup->id } ) && $allow_locs{ $allow_row->cachegroup->id } == 1 ) )
{
my $ipv4 = NetAddr::IP->new( $allow_row->ip_address, $allow_row->ip_netmask );
if ( defined($ipv4) ) {
push( @allowed_netaddrips, $ipv4 );
}
else {
$self->app->log->error(
$allow_row->host_name . " has an invalid IPv4 address; excluding from ip_allow data for " . $server->host_name );
}
if ( defined $allow_row->ip6_address ) {
my $ipv6 = NetAddr::IP->new( $allow_row->ip6_address );
if ( defined($ipv6) ) {
push( @allowed_ipv6_netaddrips, NetAddr::IP->new( $allow_row->ip6_address ) );
}
else {
$self->app->log->error(
$allow_row->host_name . " has an invalid IPv6 address; excluding from ip_allow data for " . $server->host_name );
}
}
}
}
# compact, coalesce and compact combined list again
# if more than 5 servers are in a /24, list that /24 - TODO JvD: parameterize
my @compacted_list = NetAddr::IP::Compact(@allowed_netaddrips);
my $coalesced_list = NetAddr::IP::Coalesce( 24, 5, @allowed_netaddrips );
my @combined_list = NetAddr::IP::Compact( @allowed_netaddrips, @{$coalesced_list} );
foreach my $net (@combined_list) {
my $range = $net->range();
$range =~ s/\s+//g;
$ipallow->[$i]->{src_ip} = $range;
$ipallow->[$i]->{action} = "ip_allow";
$ipallow->[$i]->{method} = "ALL";
$i++;
}
# now add IPv6. TODO JvD: paremeterize support enabled on/ofd and /48 and number 5
my @compacted__ipv6_list = NetAddr::IP::Compact(@allowed_ipv6_netaddrips);
my $coalesced_ipv6_list = NetAddr::IP::Coalesce( 48, 5, @allowed_ipv6_netaddrips );
my @combined_ipv6_list = NetAddr::IP::Compact( @allowed_ipv6_netaddrips, @{$coalesced_ipv6_list} );
foreach my $net (@combined_ipv6_list) {
my $range = $net->range();
$range =~ s/\s+//g;
$ipallow->[$i]->{src_ip} = $range;
$ipallow->[$i]->{action} = "ip_allow";
$ipallow->[$i]->{method} = "ALL";
$i++;
}
# allow RFC 1918 server space - TODO JvD: parameterize
$ipallow->[$i]->{src_ip} = '10.0.0.0-10.255.255.255';
$ipallow->[$i]->{action} = 'ip_allow';
$ipallow->[$i]->{method} = "ALL";
$i++;
$ipallow->[$i]->{src_ip} = '172.16.0.0-172.31.255.255';
$ipallow->[$i]->{action} = 'ip_allow';
$ipallow->[$i]->{method} = "ALL";
$i++;
$ipallow->[$i]->{src_ip} = '192.168.0.0-192.168.255.255';
$ipallow->[$i]->{action} = 'ip_allow';
$ipallow->[$i]->{method} = "ALL";
$i++;
# end with a deny
$ipallow->[$i]->{src_ip} = '0.0.0.0-255.255.255.255';
$ipallow->[$i]->{action} = 'ip_deny';
$ipallow->[$i]->{method} = "ALL";
$i++;
$ipallow->[$i]->{src_ip} = '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
$ipallow->[$i]->{action} = 'ip_deny';
$ipallow->[$i]->{method} = "ALL";
$i++;
}
else {
# for edges deny "PUSH|PURGE|DELETE", allow everything else to everyone.
$ipallow->[$i]->{src_ip} = '0.0.0.0-255.255.255.255';
$ipallow->[$i]->{action} = 'ip_deny';
$ipallow->[$i]->{method} = "PUSH|PURGE|DELETE";
$i++;
$ipallow->[$i]->{src_ip} = '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff';
$ipallow->[$i]->{action} = 'ip_deny';
$ipallow->[$i]->{method} = "PUSH|PURGE|DELETE";
$i++;
}
return $ipallow;
}
sub facts {
my $self = shift;
my $id = shift;
my $filename = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
$text .= "profile:" . $server->profile->name . "\n";
return $text;
}
sub logs_xml_dot_config {
my $self = shift;
my $id = shift;
my $filename = shift;
my $server = $self->server_data($id);
my $data = $self->param_data( $server, $filename );
my $text = "<!-- Generated for " . $server->host_name . " by " . &name_version_string($self) . " - Do not edit!! -->\n";
my $log_format_name = $data->{"LogFormat.Name"} || "";
my $log_object_filename = $data->{"LogObject.Filename"} || "";
my $log_object_format = $data->{"LogObject.Format"} || "";
my $log_object_rolling_enabled = $data->{"LogObject.RollingEnabled"} || "";
my $log_object_rolling_interval_sec = $data->{"LogObject.RollingIntervalSec"} || "";
my $log_object_rolling_offset_hr = $data->{"LogObject.RollingOffsetHr"} || "";
my $log_object_rolling_size_mb = $data->{"LogObject.RollingSizeMb"} || "";
my $format = $data->{"LogFormat.Format"};
$format =~ s/"/\\\"/g;
$text .= "<LogFormat>\n";
$text .= " <Name = \"" . $log_format_name . "\"/>\n";
$text .= " <Format = \"" . $format . "\"/>\n";
$text .= "</LogFormat>\n";
$text .= "<LogObject>\n";
$text .= " <Format = \"" . $log_object_format . "\"/>\n";
$text .= " <Filename = \"" . $log_object_filename . "\"/>\n";
$text .= " <RollingEnabled = " . $log_object_rolling_enabled . "/>\n" unless defined();
$text .= " <RollingIntervalSec = " . $log_object_rolling_interval_sec . "/>\n";
$text .= " <RollingOffsetHr = " . $log_object_rolling_offset_hr . "/>\n";
$text .= " <RollingSizeMb = " . $log_object_rolling_size_mb . "/>\n";
$text .= "</LogObject>\n";
return $text;
}
sub cacheurl_dot_config {
my $self = shift;
my $id = shift;
my $filename = shift;
my $data = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
if ( !defined($data) ) {
$data = $self->ds_data($server);
}
if ( $filename eq "cacheurl_qstring.config" ) { # This is the per remap drop qstring w cacheurl use case, the file is the same for all remaps
$text .= "http://([^?]+)(?:\\?|\$) http://\$1\n";
$text .= "https://([^?]+)(?:\\?|\$) https://\$1\n";
}
elsif ( $filename =~ /cacheurl_(.*).config/ )
{ # Yes, it's possibe to have the same plugin invoked multiple times on the same remap line, this is from the remap entry
my $ds_xml_id = $1;
my $ds = $self->db->resultset('Deliveryservice')->search( { xml_id => $ds_xml_id }, { prefetch => [ 'type', 'profile' ] } )->single();
if ($ds) {
$text .= $ds->cacheurl . "\n";
}
}
elsif ( $filename eq "cacheurl.config" ) { # this is the global drop qstring w cacheurl use case
foreach my $remap ( @{ $data->{dslist} } ) {
if ( $remap->{qstring_ignore} == 1 ) {
my $org = $remap->{org};
$org =~ /(https?:\/\/)(.*)/;
$text .= "$1(" . $2 . "/[^?]+)(?:\\?|\$) $1\$1\n";
}
}
}
$text =~ s/\s*__RETURN__\s*/\n/g;
return $text;
}
# generic key $separator value pairs from the data hash
sub url_sig_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $sep = defined( $separator->{$file} ) ? $separator->{$file} : " = ";
my $server = $self->server_data($id);
my $data = $self->param_data( $server, $file );
my $text = $self->header_comment( $server->host_name );
my $response_container = $self->riak_get( URL_SIG_KEYS_BUCKET, $file );
my $response = $response_container->{response};
if ( $response->is_success() ) {
my $response_json = decode_json( $response->content );
my $keys = $response_json;
foreach my $parameter ( sort keys %{$data} ) {
if ( !defined($keys) || $parameter !~ /^key\d+/ ) { # only use key parameters as a fallback (temp, remove me later)
$text .= $parameter . $sep . $data->{$parameter} . "\n";
}
}
# $self->app->log->debug( "keys #-> " . Dumper($keys) );
foreach my $parameter ( sort keys %{$keys} ) {
$text .= $parameter . $sep . $keys->{$parameter} . "\n";
}
return $text;
}
else {
my $error = $response->content;
return "Error: " . $error;
}
}
# generic key $separator value pairs from the data hash
sub generic_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $sep = defined( $separator->{$file} ) ? $separator->{$file} : " = ";
my $server = $self->server_data($id);
my $data = $self->param_data( $server, $file );
my $text = $self->header_comment( $server->host_name );
foreach my $parameter ( sort keys %{$data} ) {
my $p_name = $parameter;
$p_name =~ s/__\d+$//;
$text .= $p_name . $sep . $data->{$parameter} . "\n";
}
return $text;
}
sub get_num_volumes {
my $data = shift;
my $num = 0;
my @drive_prefixes = qw( Drive_Prefix SSD_Drive_Prefix RAM_Drive_Prefix);
foreach my $pre (@drive_prefixes) {
if ( exists $data->{$pre} ) {
$num++;
}
}
return $num;
}
sub volume_dot_config_volume_text {
my $volume = shift;
my $num_volumes = shift;
my $size = int( 100 / $num_volumes );
return "volume=$volume scheme=http size=$size%\n";
}
sub volume_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $data = $self->param_data( $server, "storage.config" );
my $text = $self->header_comment( $server->host_name );
my $num_volumes = get_num_volumes($data);
my $next_volume = 1;
$text .= "# 12M NOTE: This is running with forced volumes - the size is irrelevant\n";
if ( defined( $data->{Drive_Prefix} ) ) {
$text .= volume_dot_config_volume_text( $next_volume, $num_volumes );
$next_volume++;
}
if ( defined( $data->{RAM_Drive_Prefix} ) ) {
$text .= volume_dot_config_volume_text( $next_volume, $num_volumes );
$next_volume++;
}
if ( defined( $data->{SSD_Drive_Prefix} ) ) {
$text .= volume_dot_config_volume_text( $next_volume, $num_volumes );
$next_volume++;
}
return $text;
}
sub hosting_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $data = shift;
my $server = $self->server_data($id);
my $storage_data = $self->param_data( $server, "storage.config" );
my $text = $self->header_comment( $server->host_name );
if ( !defined($data) ) {
$data = $self->ds_data($server);
}
if ( defined( $storage_data->{RAM_Drive_Prefix} ) ) {
my $next_volume = 1;
if ( defined( $storage_data->{Drive_Prefix} ) ) {
my $disk_volume = $next_volume;
$text .= "# 12M NOTE: volume " . $disk_volume . " is the Disk volume\n";
$next_volume++;
}
my $ram_volume = $next_volume;
$text .= "# 12M NOTE: volume " . $ram_volume . " is the RAM volume\n";
my %listed = ();
foreach my $remap ( @{ $data->{dslist} } ) {
if ( ( ( $remap->{type} =~ /_LIVE$/ || $remap->{type} =~ /_LIVE_NATNL$/ ) && $server->type->name =~ m/^EDGE/ )
|| ( $remap->{type} =~ /_LIVE_NATNL$/ && $server->type->name =~ m/^MID/ ) )
{
if ( defined( $listed{ $remap->{org} } ) ) { next; }
my $org_fqdn = $remap->{org};
$org_fqdn =~ s/https?:\/\///;
$text .= "hostname=" . $org_fqdn . " volume=" . $ram_volume . "\n";
$listed{ $remap->{org} } = 1;
}
}
}
my $disk_volume = 1; # note this will actually be the RAM (RAM_Drive_Prefix) volume if there is no Drive_Prefix parameter.
$text .= "hostname=* volume=" . $disk_volume . "\n";
return $text;
}
sub storage_dot_config_volume_text {
my $prefix = shift;
my $letters = shift;
my $volume = shift;
my $text = "";
my @postfix = split( /,/, $letters );
foreach my $l ( sort @postfix ) {
$text .= $prefix . $l;
$text .= " volume=" . $volume;
$text .= "\n";
}
return $text;
}
sub storage_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
my $data = $self->param_data( $server, $file );
my $next_volume = 1;
if ( defined( $data->{Drive_Prefix} ) ) {
$text .= storage_dot_config_volume_text( $data->{Drive_Prefix}, $data->{Drive_Letters}, $next_volume );
$next_volume++;
}
if ( defined( $data->{RAM_Drive_Prefix} ) ) {
$text .= storage_dot_config_volume_text( $data->{RAM_Drive_Prefix}, $data->{RAM_Drive_Letters}, $next_volume );
$next_volume++;
}
if ( defined( $data->{SSD_Drive_Prefix} ) ) {
$text .= storage_dot_config_volume_text( $data->{SSD_Drive_Prefix}, $data->{SSD_Drive_Letters}, $next_volume );
$next_volume++;
}
return $text;
}
sub ats_dot_rules {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
my $data = $self->param_data( $server, "storage.config" ); # ats.rules is based on the storage.config params
my $drive_prefix = $data->{Drive_Prefix};
my @drive_postfix = split( /,/, $data->{Drive_Letters} );
foreach my $l ( sort @drive_postfix ) {
$drive_prefix =~ s/\/dev\///;
$text .= "KERNEL==\"" . $drive_prefix . $l . "\", OWNER=\"ats\"\n";
}
if ( defined( $data->{RAM_Drive_Prefix} ) ) {
$drive_prefix = $data->{RAM_Drive_Prefix};
@drive_postfix = split( /,/, $data->{RAM_Drive_Letters} );
foreach my $l ( sort @drive_postfix ) {
$drive_prefix =~ s/\/dev\///;
$text .= "KERNEL==\"" . $drive_prefix . $l . "\", OWNER=\"ats\"\n";
}
}
return $text;
}
sub cache_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $data = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
if ( !defined($data) ) {
$data = $self->ds_data($server);
}
foreach my $remap ( @{ $data->{dslist} } ) {
if ( $remap->{type} eq "HTTP_NO_CACHE" ) {
my $org_fqdn = $remap->{org};
$org_fqdn =~ s/https?:\/\///;
$text .= "dest_domain=" . $org_fqdn . " scheme=http action=never-cache\n";
}
}
return $text;
}
sub remap_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $data = shift;
my $server = $self->server_data($id);
my $pdata = $self->param_data( $server, 'package' );
my $text = $self->header_comment( $server->host_name );
if ( !defined($data) ) {
$data = $self->ds_data($server);
}
if ( $server->type->name =~ m/^MID/ ) {
my %mid_remap;
foreach my $remap ( @{ $data->{dslist} } ) {
if ( $remap->{type} =~ /LIVE/ && $remap->{type} !~ /NATNL/ ) {
next; # Live local delivery services skip mids
}
if ( defined( $mid_remap{ $remap->{org} } ) ) {
next; # skip remap rules from extra HOST_REGEXP entries
}
if ( defined( $remap->{mid_header_rewrite} ) && $remap->{mid_header_rewrite} ne "" ) {
$mid_remap{ $remap->{org} } .= " \@plugin=header_rewrite.so \@pparam=" . $remap->{mid_hdr_rw_file};
}
if ( $remap->{qstring_ignore} == 1 ) {
$mid_remap{ $remap->{org} } .= " \@plugin=cacheurl.so \@pparam=cacheurl_qstring.config";
}
if ( defined( $remap->{cacheurl} ) && $remap->{cacheurl} ne "" ) {
$mid_remap{ $remap->{org} } .= " \@plugin=cacheurl.so \@pparam=" . $remap->{cacheurl_file};
}
if ( $remap->{range_request_handling} == 2 ) {
$mid_remap{ $remap->{org} } .= " \@plugin=cache_range_requests.so";
}
}
foreach my $key ( keys %mid_remap ) {
$text .= "map " . $key . " " . $key . $mid_remap{$key} . "\n";
}
return $text;
}
# mids don't get here.
foreach my $remap ( @{ $data->{dslist} } ) {
foreach my $map_from ( keys %{ $remap->{remap_line} } ) {
my $map_to = $remap->{remap_line}->{$map_from};
$text = $self->build_remap_line( $server, $pdata, $text, $data, $remap, $map_from, $map_to );
}
foreach my $map_from ( keys %{ $remap->{remap_line2} } ) {
my $map_to = $remap->{remap_line2}->{$map_from};
$text = $self->build_remap_line( $server, $pdata, $text, $data, $remap, $map_from, $map_to );
}
}
return $text;
}
sub build_remap_line {
my $self = shift;
my $server = shift;
my $pdata = shift;
my $text = shift;
my $data = shift;
my $remap = shift;
my $map_from = shift;
my $map_to = shift;
if ( $remap->{type} eq 'ANY_MAP' ) {
$text .= $remap->{remap_text} . "\n";
return $text;
}
my $host_name = $data->{host_name};
my $dscp = $remap->{dscp};
$map_from =~ s/ccr/$host_name/;
if ( defined( $pdata->{'dscp_remap'} ) ) {
$text .= "map " . $map_from . " " . $map_to . " \@plugin=dscp_remap.so \@pparam=" . $dscp;
}
else {
$text .= "map " . $map_from . " " . $map_to . " \@plugin=header_rewrite.so \@pparam=dscp/set_dscp_" . $dscp . ".config";
}
if ( defined( $remap->{edge_header_rewrite} ) ) {
$text .= " \@plugin=header_rewrite.so \@pparam=" . $remap->{hdr_rw_file};
}
if ( $remap->{signed} == 1 ) {
$text .= " \@plugin=url_sig.so \@pparam=url_sig_" . $remap->{ds_xml_id} . ".config";
}
if ( $remap->{qstring_ignore} == 2 ) {
my $dqs_file = "drop_qstring.config";
$text .= " \@plugin=regex_remap.so \@pparam=" . $dqs_file;
}
elsif ( $remap->{qstring_ignore} == 1 ) {
my $global_exists = $self->profile_param_value( $server->profile->id, 'cacheurl.config', 'location', undef );
if ($global_exists) {
$self->app->log->debug(
"qstring_ignore == 1, but global cacheurl.config param exists, so skipping remap rename config_file=cacheurl.config parameter if you want to change"
);
}
else {
$text .= " \@plugin=cacheurl.so \@pparam=cacheurl_qstring.config";
}
}
if ( defined( $remap->{cacheurl} ) && $remap->{cacheurl} ne "" ) {
$text .= " \@plugin=cacheurl.so \@pparam=" . $remap->{cacheurl_file};
}
# Note: should use full path here?
if ( defined( $remap->{regex_remap} ) && $remap->{regex_remap} ne "" ) {
$text .= " \@plugin=regex_remap.so \@pparam=regex_remap_" . $remap->{ds_xml_id} . ".config";
}
if ( $remap->{range_request_handling} == 1 ) {
$text .= " \@plugin=background_fetch.so \@pparam=bg_fetch.config";
}
elsif ( $remap->{range_request_handling} == 2 ) {
$text .= " \@plugin=cache_range_requests.so ";
}
if ( defined( $remap->{remap_text} ) ) {
$text .= " " . $remap->{remap_text};
}
$text .= "\n";
return $text;
}
sub format_parent_info {
my $parent = shift;
if ( !defined $parent ) {
return ""; # should never happen..
}
my $host =
( $parent->{use_ip_address} == 1 )
? $parent->{ip_address}
: $parent->{host_name} . '.' . $parent->{domain_name};
my $port = $parent->{port};
my $weight = $parent->{weight};
my $text = "$host:$port|$weight;";
return $text;
}
sub parent_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $data = shift;
my $server = $self->server_data($id);
my $server_type = $server->type->name;
my $text = $self->header_comment( $server->host_name );
if ( !defined($data) ) {
$data = $self->ds_data($server);
}
# Origin Shield or Multi Site Origin
#$self->app->log->debug( "id = $id and server_type = $server_type, hostname = " . $server->{host_name} );
if ( $server_type =~ m/^MID/ ) {
foreach my $ds ( @{ $data->{dslist} } ) {
my $xml_id = $ds->{ds_xml_id};
my $os = $ds->{origin_shield};
my $multi_site_origin = defined( $ds->{multi_site_origin} ) ? $ds->{multi_site_origin} : 0;
my $multi_site_origin_algorithm = defined( $ds->{multi_site_origin_algorithm} ) ? $ds->{multi_site_origin_algorithm} : 0;
my $org_fqdn = $ds->{org};
$org_fqdn =~ s/https?:\/\///;
if ( defined($os) ) {
my $pselect_alg = $self->profile_param_value( $server->profile->id, 'parent.config', 'algorithm', undef );
my $algorithm = "";
if ( defined($pselect_alg) ) {
$algorithm = "round_robin=$pselect_alg";
}
$text .= "dest_domain=$org_fqdn parent=$os $algorithm go_direct=true\n";
}
elsif ($multi_site_origin) {
$text .= "dest_domain=$org_fqdn ";
my $pinfo = $self->parent_data($server);
my @ranked_parents = ();
if ( exists( $pinfo->{$org_fqdn} ) ) {
@ranked_parents = sort by_parent_rank @{ $pinfo->{$org_fqdn} };
}
my @parent_info;
foreach my $parent (@ranked_parents) {
push @parent_info, format_parent_info($parent);
}
my %seen;
@parent_info = grep { !$seen{$_}++ } @parent_info;
my $parents = 'parent="' . join( '', @parent_info ) . '"';
my $mso_algorithm = "";
if ( $multi_site_origin_algorithm == 0 ) {
$mso_algorithm = "consistent_hash";
}
elsif ( $multi_site_origin_algorithm == 1 ) {
$mso_algorithm = "false";
}
elsif ( $multi_site_origin_algorithm == 2 ) {
$mso_algorithm = "strict";
}
elsif ( $multi_site_origin_algorithm == 3 ) {
$mso_algorithm = "true";
}
else {
$mso_algorithm = "consistent_hash";
}
$text .= "$parents round_robin=$mso_algorithm go_direct=false parent_is_proxy=false\n";
}
}
#$text .= "dest_domain=. go_direct=true\n"; # this is implicit.
$self->app->log->debug( "MID PARENT.CONFIG:\n" . $text . "\n" );
return $text;
}
else {
#"True" Parent
my $pinfo = $self->parent_data($server);
my %done = ();
foreach my $remap ( @{ $data->{dslist} } ) {
my $org = $remap->{org};
next if !defined $org || $org eq "";
next if $done{$org};
if ( $remap->{type} eq "HTTP_NO_CACHE" || $remap->{type} eq "HTTP_LIVE" || $remap->{type} eq "DNS_LIVE" ) {
my $org_fqdn = $remap->{org};
$org_fqdn =~ s/https?:\/\///;
$text .= "dest_domain=" . $org_fqdn . " go_direct=true\n";
}
else {
my $org_fqdn = $remap->{org};
$org_fqdn =~ s/https?:\/\///;
my $qstring = $self->profile_param_value( $server->profile->id, 'parent.config', 'qstring', undef );
$qstring = ( defined $qstring ) ? "qstring=$qstring" : '';
my @parent_info;
my @secondary_parent_info;
foreach my $parent ( @{ $pinfo->{all_parents} } ) {
my $ptxt = format_parent_info($parent);
if ( $parent->{parent} ) {
push @parent_info, $ptxt;
}
elsif ( $parent->{secondary} ) {
push @secondary_parent_info, $ptxt;
}
}
my %seen;
@parent_info = grep { !$seen{$_}++ } @parent_info;
my $parents = 'parent="' . join( '', @parent_info ) . '"';
my $secparents = '';
if ( scalar @secondary_parent_info > 0 ) {
my %seen;
@secondary_parent_info = grep { !$seen{$_}++ } @secondary_parent_info;
$secparents = 'secondary_parent="' . join( '', @secondary_parent_info ) . '"';
}
my $round_robin = 'round_robin=consistent_hash';
my $go_direct = 'go_direct=false';
$text .= "dest_domain=$org_fqdn $parents $secparents $round_robin $go_direct $qstring\n";
}
$done{$org} = 1;
}
my $pselect_alg = $self->profile_param_value( $server->profile->id, 'parent.config', 'algorithm', undef );
if ( defined($pselect_alg) && $pselect_alg eq 'consistent_hash' ) {
my @parent_info;
foreach my $parent ( @{ $pinfo->{"all_parents"} } ) {
push @parent_info, $parent->{"host_name"} . "." . $parent->{"domain_name"} . ":" . $parent->{"port"} . "|" . $parent->{"weight"} . ";";
}
my %seen;
@parent_info = grep { !$seen{$_}++ } @parent_info;
$text .= "dest_domain=.";
$text .= " parent=\"" . join( '', @parent_info ) . "\"";
$text .= " round_robin=consistent_hash go_direct=false";
}
else { # default to old situation.
$text .= "dest_domain=.";
my @parent_info;
foreach my $parent ( @{ $pinfo->{"all_parents"} } ) {
push @parent_info, $parent->{"host_name"} . "." . $parent->{"domain_name"} . ":" . $parent->{"port"} . ";";
}
my %seen;
@parent_info = grep { !$seen{$_}++ } @parent_info;
$text .= " parent=\"" . join( '', @parent_info ) . "\"";
$text .= " round_robin=urlhash go_direct=false";
}
my $qstring = $self->profile_param_value( $server->profile->id, 'parent.config', 'qstring', undef );
if ( defined($qstring) ) {
$text .= " qstring=" . $qstring;
}
$text .= "\n";
# $self->app->log->debug($text);
return $text;
}
}
sub ip_allow_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
my $data = $self->ip_allow_data( $server, $file );
foreach my $access ( @{$data} ) {
$text .= sprintf( "src_ip=%-70s action=%-10s method=%-20s\n", $access->{src_ip}, $access->{action}, $access->{method} );
}
return $text;
}
sub regex_revalidate_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
# note: Calling this from outside Configfiles, so $self->method doesn't work. TODO: Be smarter
# my $server = $self->server_data($id);
# my $text = $self->header_comment( $server->host_name );
my $server = &server_data( $self, $id );
my $text = "# DO NOT EDIT - Generated for CDN " . $server->cdn->name . " by " . &name_version_string($self) . " on " . `date`;
my $max_days =
$self->db->resultset('Parameter')->search( { name => "maxRevalDurationDays" }, { config_file => "regex_revalidate.config" } )->get_column('value')
->single;
my $interval = "> now() - interval '$max_days day'"; # postgres
if ( $self->db->storage->isa("DBIx::Class::Storage::DBI::mysql") ) {
$interval = "> now() - interval $max_days day";
}
my %regex_time;
my $max_days =
$self->db->resultset('Parameter')->search( { name => "ttl_max_hours" }, { config_file => "regex_revalidate.config" } )->get_column('value')->first;
my $max_hours = $max_days * 24;
my $min_hours = 1;
my $rs = $self->db->resultset('Job')->search( { start_time => \$interval }, { prefetch => 'job_deliveryservice' } );
while ( my $row = $rs->next ) {
next unless defined( $row->job_deliveryservice );
# Purges are CDN - wide, and the job entry has the ds id in it.
my $parameters = $row->parameters;
my $ttl;
if ( $row->keyword eq "PURGE" && ( defined($parameters) && $parameters =~ /TTL:(\d+)h/ ) ) {
$ttl = $1;
if ( $ttl < $min_hours ) {
$ttl = $min_hours;
}
elsif ( $ttl > $max_hours ) {
$ttl = $max_hours;
}
}
else {
next;
}
my $date = new Date::Manip::Date();
my $start_time = $row->start_time;
my $start_date = ParseDate($start_time);
my $end_date = DateCalc( $start_date, ParseDateDelta( $ttl . ':00:00' ) );
my $err = $date->parse($end_date);
if ($err) {
print "ERROR ON DATE CONVERSION:" . $err;
next;
}
my $purge_end = $date->printf("%s"); # this is in secs since the unix epoch
if ( $purge_end < time() ) { # skip purges that have an end_time in the past
next;
}
my $asset_url = $row->asset_url;
my $job_cdn_id = $row->job_deliveryservice->cdn_id;
if ( $server->cdn_id == $job_cdn_id ) {
# if there are multipe with same re, pick the longes lasting.
if ( !defined( $regex_time{ $row->asset_url } )
|| ( defined( $regex_time{ $row->asset_url } ) && $purge_end > $regex_time{ $row->asset_url } ) )
{
$regex_time{ $row->asset_url } = $purge_end;
}
}
}
foreach my $re ( sort keys %regex_time ) {
$text .= $re . " " . $regex_time{$re} . "\n";
}
return $text;
}
sub take_and_bake {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $data = $self->param_data( $server, $file );
my $text = $self->header_comment( $server->host_name );
foreach my $parameter ( sort keys %{$data} ) {
$text .= $data->{$parameter} . "\n";
}
return $text;
}
sub drop_qstring_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
$server = &server_data( $self, $id );
my $drop_qstring = $self->profile_param_value( $server->profile->id, 'drop_qstring.config', 'content', undef );
if ($drop_qstring) {
$text .= $drop_qstring . "\n";
}
else {
$text .= "/([^?]+) \$s://\$t/\$1\n";
}
return $text;
}
sub header_rewrite_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
my $ds_xml_id = undef;
if ( $file =~ /^hdr_rw_mid_(.*)\.config$/ ) {
$ds_xml_id = $1;
my $ds = $self->db->resultset('Deliveryservice')->search( { xml_id => $ds_xml_id }, { prefetch => [ 'type', 'profile' ] } )->single();
my $actions = $ds->mid_header_rewrite;
$text .= $actions . "\n";
}
elsif ( $file =~ /^hdr_rw_(.*)\.config$/ ) {
$ds_xml_id = $1;
my $ds = $self->db->resultset('Deliveryservice')->search( { xml_id => $ds_xml_id }, { prefetch => [ 'type', 'profile' ] } )->single();
my $actions = $ds->edge_header_rewrite;
$text .= $actions . "\n";
}
$text =~ s/\s*__RETURN__\s*/\n/g;
my $ipv4 = $server->ip_address;
$text =~ s/__CACHE_IPV4__/$ipv4/g;
return $text;
}
sub regex_remap_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
if ( $file =~ /^regex_remap_(.*)\.config$/ ) {
my $ds_xml_id = $1;
my $ds = $self->db->resultset('Deliveryservice')->search( { xml_id => $ds_xml_id }, { prefetch => [ 'type', 'profile' ] } )->single();
$text .= $ds->regex_remap . "\n";
}
$text =~ s/\s*__RETURN__\s*/\n/g;
return $text;
}
sub header_rewrite_dscp_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
my $dscp_decimal;
if ( $file =~ /^set_dscp_(\d+)\.config$/ ) {
$dscp_decimal = $1;
}
else {
$text = "An error occured generating the DSCP header rewrite file.";
}
$text .= "cond %{REMAP_PSEUDO_HOOK}\n" . "set-conn-dscp " . $dscp_decimal . " [L]\n";
return $text;
}
sub to_ext_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
# get the subroutine name for this file from the parameter
my $subroutine = $self->profile_param_value( $server->profile->id, $file, 'SubRoutine', undef );
$self->app->log->error( "ToExtDotConfigFile == " . $subroutine );
# TODO: previous code didn't check for undef -- what to do here?
if ( defined $subroutine ) {
my $package;
( $package = $subroutine ) =~ s/(.*)(::)(.*)/$1/;
eval "use $package;";
# And call it - the below calls the subroutine in the var $subroutine.
no strict 'refs';
$text .= $subroutine->( $self, $id, $file );
# $text .= &{ \&{$subroutine} }( $self, $id, $file );
}
return $text;
}
sub ssl_multicert_dot_config {
my $self = shift;
my $id = shift;
my $file = shift;
#id == hostname
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
# get a list of delivery services for the server
my $protocol_search = '> 0';
my @ds_list = $self->db->resultset('Deliveryservice')->search( { -and => [ 'server.id' => $server->id, 'me.protocol' => \$protocol_search ] },
{ join => { deliveryservice_servers => { server => undef } }, } );
foreach my $ds (@ds_list) {
my $ds_id = $ds->id;
my $xml_id = $ds->xml_id;
my $rs_ds = $self->db->resultset('Deliveryservice')->search( { 'me.id' => $ds_id } );
my $data = $rs_ds->single;
my $domain_name = UI::DeliveryService::get_cdn_domain( $self, $ds_id );
my $ds_regexes = UI::DeliveryService::get_regexp_set( $self, $ds_id );
my @example_urls = UI::DeliveryService::get_example_urls( $self, $ds_id, $ds_regexes, $data, $domain_name, $data->protocol );
#first one is the one we want
my $hostname = $example_urls[0];
$hostname =~ /(https?:\/\/)(.*)/;
my $new_host = $2;
my $key_name = "$new_host.key";
$new_host =~ tr/./_/;
my $cer_name = $new_host . "_cert.cer";
$text .= "ssl_cert_name=$cer_name\t ssl_key_name=$key_name\n";
}
return $text;
}
# This is a temporary workaround until we have real partial object caching support in ATS, so hardcoding for now
sub bg_fetch_dot_config {
my $self = shift;
my $id = shift;
my $server = $self->server_data($id);
my $text = $self->header_comment( $server->host_name );
$text .= "include User-Agent *\n";
return $text;
}
1;