Skip to content

Commit

Permalink
Add Traffic Ops Geo Limit Country Codes
Browse files Browse the repository at this point in the history
Adds a UI field to enter comma-separated ISO 3166-1 alpha-2 country
codes, which are validated.

Adds a database column in the deliveryservice table for country codes.

Adds country codes to CRConfig, if Geo Limit is set to include them.

Resolves Comcast#1403
  • Loading branch information
rob05c committed May 11, 2016
1 parent 68e5ac9 commit dd36913
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright 2016 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.
*/

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
alter table deliveryservice add column geo_limit_countries varchar(750); -- 250 country codes * (2 letters plus a comma)
update deliveryservice set geo_limit_countries = "US" where geo_limit = 2;
update deliveryservice set geo_limit_countries = "CA" where geo_limit = 3;
update deliveryservice set geo_limit = 2 where geo_limit = 3;

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
alter table deliveryservice drop column geo_limit_countries;
1 change: 1 addition & 0 deletions traffic_ops/app/lib/API/DeliveryService.pm
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ sub delivery_services {
"signed" => \$row->signed,
"qstringIgnore" => $row->qstring_ignore,
"geoLimit" => $row->geo_limit,
"geoLimitCountries" => $row->geo_limit_countries,
"geoProvider" => $row->geo_provider,
"httpBypassFqdn" => $row->http_bypass_fqdn,
"dnsBypassIp" => $row->dns_bypass_ip,
Expand Down
7 changes: 7 additions & 0 deletions traffic_ops/app/lib/Schema/Result/Deliveryservice.pm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ __PACKAGE__->table("deliveryservice");
default_value: 0
is_nullable: 1
=head2 geo_limit_countries
data_type: 'varchar'
is_nullable: 1
=head2 geo_provider
data_type: 'tinyint'
Expand Down Expand Up @@ -299,6 +304,8 @@ __PACKAGE__->add_columns(
{ data_type => "tinyint", is_nullable => 1 },
"geo_limit",
{ data_type => "tinyint", default_value => 0, is_nullable => 1 },
"geo_limit_countries",
{ data_type => "varchar", is_nullable => 1 },
"geo_provider",
{ data_type => "tinyint", default_value => 0, is_nullable => 0 },
"http_bypass_fqdn",
Expand Down
21 changes: 21 additions & 0 deletions traffic_ops/app/lib/UI/DeliveryService.pm
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ sub read {
"signed" => \$row->signed,
"qstring_ignore" => $row->qstring_ignore,
"geo_limit" => $row->geo_limit,
"geo_limit_countries" => $row->geo_limit_countries,
"geo_provider" => $row->geo_provider,
"http_bypass_fqdn" => $row->http_bypass_fqdn,
"dns_bypass_ip" => $row->dns_bypass_ip,
Expand Down Expand Up @@ -301,6 +302,13 @@ sub typename {
return $self->param('type.name') // $self->db->resultset('Type')->search( { id => $self->typeid() } )->get_column('name')->single();
}

sub sanitize_geo_limit_countries {
my $geo_limit_countries = shift;
$geo_limit_countries =~ s/\s+//g;
$geo_limit_countries = uc($geo_limit_countries);
return $geo_limit_countries
}

sub check_deliveryservice_input {
my $self = shift;

Expand Down Expand Up @@ -498,6 +506,17 @@ sub check_deliveryservice_input {
}
}

my @valid_country_codes_list = qw/AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM BT BO BQ BA BW BV BR IO BN BG BF BI CV KH CM CA KY CF TD CL CN CX CC CO KM CG CD CK CR CI HR CU CW CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU GT GG GN GW Y HT HM VA HN HK HU IS IN ID IR IQ IE IM IL IT JM JP JE JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS MA MZ MM NA NR NP NL NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH PN PL PT PR QA RE RO RU RW BL SH KN LC F PM VC WS SM ST SA SN RS SC SL SG SX SK SI SB SO ZA GS SS ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TL TG TK TO TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VE VN VG VI WF EH YE ZM ZW/;
my %valid_country_codes;
@valid_country_codes{@valid_country_codes_list} = ();
my @geo_limit_country_codes = split(',', sanitize_geo_limit_countries($self->paramAsScalar('ds.geo_limit_countries')));
foreach my $country_code (@geo_limit_country_codes) {
if(!exists($valid_country_codes{$country_code})) {
$self->field('ds.geo_limit_countries')->is_equal( "", "Invalid Geo Limit Country Code. Geo limit country codes must be comma-separated ISO 3166 Alpha-2 codes." );
last;
}
}

#TODO: Fix this to work the right way.
# if ( defined( $self->param('ds.edge_header_rewrite') ) ) {
# if ( $self->param('ds.edge_header_rewrite') ne "" && $self->param('ds.edge_header_rewrite') !~ /^(?:add|rm|set)-header .* \[L\]$/ ) {
Expand Down Expand Up @@ -721,6 +740,7 @@ sub update {
signed => $self->paramAsScalar('ds.signed'),
qstring_ignore => $self->paramAsScalar('ds.qstring_ignore'),
geo_limit => $self->paramAsScalar('ds.geo_limit'),
geo_limit_countries => sanitize_geo_limit_countries($self->paramAsScalar('ds.geo_limit_countries')),
geo_provider => $self->paramAsScalar('ds.geo_provider'),
org_server_fqdn => $self->paramAsScalar('ds.org_server_fqdn'),
multi_site_origin => $self->paramAsScalar('ds.multi_site_origin'),
Expand Down Expand Up @@ -923,6 +943,7 @@ sub create {
signed => $self->paramAsScalar('ds.signed'),
qstring_ignore => $self->paramAsScalar('ds.qstring_ignore'),
geo_limit => $self->paramAsScalar('ds.geo_limit'),
geo_limit_countries => sanitize_geo_limit_countries($self->paramAsScalar('ds.geo_limit_countries')),
geo_provider => $self->paramAsScalar('ds.geo_provider'),
http_bypass_fqdn => $self->paramAsScalar('ds.http_bypass_fqdn'),
dns_bypass_ip => $self->paramAsScalar('ds.dns_bypass_ip'),
Expand Down
24 changes: 11 additions & 13 deletions traffic_ops/app/lib/UI/Topology.pm
Original file line number Diff line number Diff line change
Expand Up @@ -369,19 +369,17 @@ sub gen_crconfig_json {
}

my $geo_limit = $row->geo_limit;
if ( $geo_limit == 1 ) {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'true';
}
elsif ( $geo_limit == 2 ) {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'false';
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'geoEnabled'} = [ { 'countryCode' => 'US' } ];
}
elsif ( $geo_limit == 3 ) {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'false';
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'geoEnabled'} = [ { 'countryCode' => 'CA' } ];
}
else {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'false';
if ( $geo_limit == 0 ) {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'false';
} elsif ( $geo_limit == 1 ) {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'true';
} else {
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'coverageZoneOnly'} = 'false';
my $geoEnabled = [];
foreach my $code (split(",", $row->geo_limit_countries)) {
push(@$geoEnabled, { 'countryCode' => $code });
}
$data_obj->{'deliveryServices'}->{ $row->xml_id }->{'geoEnabled'} = $geoEnabled;
}

my $geo_provider = $row->geo_provider;
Expand Down
4 changes: 4 additions & 0 deletions traffic_ops/app/t/deliveryservice.t
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ok $t->post_ok(
'ds.dns_bypass_ttl' => '30',
'ds.dscp' => '40',
'ds.geo_limit' => '0',
'ds.geo_limit_countries' => '',
'ds.geo_provider' => '1',
'ds.global_max_mbps' => '',
'ds.global_max_tps' => '',
Expand Down Expand Up @@ -116,6 +117,7 @@ ok $t->post_ok(
'ds.dns_bypass_ttl' => '30',
'ds.dscp' => '42',
'ds.geo_limit' => '0',
'ds.geo_limit_countries' => '',
'ds.global_max_mbps' => '',
'ds.global_max_tps' => '',
'ds.http_bypass_fqdn' => '',
Expand Down Expand Up @@ -163,6 +165,7 @@ ok $t->post_ok(
'ds.dns_bypass_ttl' => '30',
'ds.dscp' => '40',
'ds.geo_limit' => '1',
'ds.geo_limit_countries' => '',
'ds.global_max_mbps' => '30G',
'ds.global_max_tps' => '10000',
'ds.http_bypass_fqdn' => 'overflow.knutsel.com',
Expand Down Expand Up @@ -234,6 +237,7 @@ ok $t->post_ok(
'ds.dns_bypass_ttl' => '31',
'ds.dscp' => '41',
'ds.geo_limit' => '0',
'ds.geo_limit_countries' => '',
'ds.geo_provider' => '1',
'ds.global_max_mbps' => '4T',
'ds.http_bypass_fqdn' => '',
Expand Down
17 changes: 13 additions & 4 deletions traffic_ops/app/templates/delivery_service/_form.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,28 @@
<% } %>
%= label_for 'geo_limit' => 'Geo Limit?', class => 'label'
<% if ($priv_level >= 20) { %>
%= field('ds.geo_limit')->select([[None => 0], ["CZF only" => 1], ["CZF + US" => 2], ["CZF + CA" => 3]]);
%= field('ds.geo_limit')->select([[None => 0], ["CZF only" => 1], ["CZF + Country Code(s)" => 2]]);
<% } else { %>
<% if ($ds->geo_limit == 0) { %>
%= field('ds.geo_limit')->text(class => 'field', value => 'None', readonly => 'readonly');
<% } elsif($ds->geo_limit == 1) { %>
%= field('ds.geo_limit')->text(class => 'field', value => 'CZF only', readonly => 'readonly');
<% } elsif($ds->geo_limit == 2) { %>
%= field('ds.geo_limit')->text(class => 'field', value => 'CZF + US', readonly => 'readonly');
<% } else { %>
%= field('ds.geo_limit')->text(class => 'field', value => 'CZF + CA', readonly => 'readonly');
%= field('ds.geo_limit')->text(class => 'field', value => 'CZF + Country Codes', readonly => 'readonly');
<% } %>
<% } %>
</div><br>
<div class="block" id="geo_limit_countries_row">
<% unless (field('ds.geo_limit_countries')->valid) { %>
<span class="field-with-error"><%= field('ds.geo_limit_countries')->error %></span>
<% } %>
%= label_for 'geo_limit_countries' => 'Geo Limit Country Codes', class => 'label'
<% if ($priv_level >= 20) { %>
%= field('ds.geo_limit_countries')->text(class => 'field', id => 'geo_limit_countries', name => 'ds.geo_limit_countries');
<% } else { %>
%= field('ds.geo_limit_countries')->text(class => 'field', readonly => 'readonly');
<% } %>
</div><br>
<div class="block" id="geo_provider_row">
<% unless (field('ds.geo_provider')->valid) { %>
<span class="field-with-error"><%= field('ds.geo_provider')->error %></span>
Expand Down

0 comments on commit dd36913

Please sign in to comment.