You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by el...@apache.org on 2018/06/14 17:22:07 UTC
[trafficcontrol] branch master updated: Remove
deliveryservice.org_server_fqdn column/compute it from Origin table
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 55d6eff Remove deliveryservice.org_server_fqdn column/compute it from Origin table
55d6eff is described below
commit 55d6eff3eab42bdf7f51ca12ec5cd92b9e7d3498
Author: Rawlin Peters <ra...@comcast.com>
AuthorDate: Mon May 21 14:42:04 2018 -0600
Remove deliveryservice.org_server_fqdn column/compute it from Origin table
With the Origin table now, the deliveryservice.org_server_fqdn column
can be removed. First, populate the Origin table from existing
deliveryservice.org_server_fqdn columns. Second, delete the
deliveryservice.org_server_fqdn column. Third, compute an
org_server_fqdn column from a deliveryservice's primary Origin wherever
needed.
This doesn't affect the API, only the APIs backend implementation, so
no new API version is needed. Whenever a DS is created, the DS's
corresponding primary Origin is created from the orgServerFqdn request
field. When a DS is updated, its primary Origin is also updated using
the orgServerFqdn request field.
As part of this, make the `isPrimary` field of the Origin API read-only,
and only allow the DeliveryService API to write/update that column in
the DB.
Added missing orgServerFqdn validation in the golang DS API to match
the perl API.
---
docs/source/api/v13/origin.rst | 8 +-
.../20180606000000_remove_org_server_fqdn.sql | 46 +++
.../app/lib/API/Configs/ApacheTrafficServer.pm | 7 +-
traffic_ops/app/lib/API/Deliveryservice.pm | 37 ++-
traffic_ops/app/lib/Fixtures/Deliveryservice.pm | 15 -
.../lib/Fixtures/Integration/Deliveryservice.pm | 8 -
traffic_ops/app/lib/Fixtures/Integration/Origin.pm | 186 +++++++++++++
traffic_ops/app/lib/Fixtures/Origin.pm | 307 +++++++++++++++++++++
traffic_ops/app/lib/MojoPlugins/Job.pm | 4 +-
traffic_ops/app/lib/Schema/Result/Cachegroup.pm | 35 ++-
traffic_ops/app/lib/Schema/Result/Coordinate.pm | 131 +++++++++
.../Result/DeliveryServiceInfoForDomainList.pm | 5 +-
.../Result/DeliveryServiceInfoForServerList.pm | 5 +-
.../app/lib/Schema/Result/Deliveryservice.pm | 38 ++-
traffic_ops/app/lib/Schema/Result/Origin.pm | 285 +++++++++++++++++++
traffic_ops/app/lib/Schema/Result/Profile.pm | 23 +-
traffic_ops/app/lib/Schema/Result/Tenant.pm | 23 +-
traffic_ops/app/lib/Test/IntegrationTestHelper.pm | 2 +
traffic_ops/app/lib/Test/TestHelper.pm | 3 +
traffic_ops/app/lib/UI/Cdn.pm | 2 +-
traffic_ops/app/lib/UI/ConfigFiles.pm | 2 +-
traffic_ops/app/lib/UI/DeliveryService.pm | 80 +++++-
traffic_ops/app/lib/UI/DeliveryServiceServer.pm | 2 +-
traffic_ops/app/lib/UI/Job.pm | 2 +-
traffic_ops/app/t/deliveryservice.t | 8 +-
traffic_ops/app/t/purge.t | 5 +-
.../app/templates/delivery_service/_form.html.ep | 10 +-
traffic_ops/testing/api/v13/tc-fixtures.json | 2 -
.../deliveryservice/deliveryservicesv12.go | 11 +-
.../deliveryservice/deliveryservicesv13.go | 140 ++++++++--
traffic_ops/traffic_ops_golang/origin/origins.go | 27 +-
.../traffic_ops_golang/origin/origins_test.go | 4 -
32 files changed, 1332 insertions(+), 131 deletions(-)
diff --git a/docs/source/api/v13/origin.rst b/docs/source/api/v13/origin.rst
index 4f96cbb..185f9ca 100644
--- a/docs/source/api/v13/origin.rst
+++ b/docs/source/api/v13/origin.rst
@@ -48,6 +48,8 @@ Origin
+-------------------------+-----------------+---------------------------------------------------+
| ``profileId`` | no | Filter Origins by profile ID. |
+-------------------------+-----------------+---------------------------------------------------+
+ | ``primary`` | no | Filter Origins by isPrimary. |
+ +-------------------------+-----------------+---------------------------------------------------+
| ``tenant`` | no | Filter Origins by tenant ID. |
+-------------------------+-----------------+---------------------------------------------------+
@@ -171,8 +173,6 @@ Origin
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``ipAddress`` | no | IPv4 address of the Origin |
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
- | ``isPrimary`` | yes | Whether or not this is the primary Origin for the delivery service |
- +-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``name`` | yes | The name of the Origin |
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``port`` | no | The TCP port on which the Origin listens |
@@ -193,7 +193,6 @@ Origin
"fqdn": "foo.example.com",
"ip6Address": "cafe:dead:d0d0::42",
"ipAddress": "10.2.3.4",
- "isPrimary": false,
"name": "origin1",
"port": 443,
"profileId": 1,
@@ -320,8 +319,6 @@ Origin
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``ipAddress`` | no | IPv4 address of the Origin |
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
- | ``isPrimary`` | yes | Whether or not this is the primary Origin for the delivery service |
- +-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``name`` | yes | The name of the Origin |
+-----------------------------------+-------------------+--------------------------------------------------------------------------+
| ``port`` | no | The TCP port on which the Origin listens |
@@ -343,7 +340,6 @@ Origin
"id": 1,
"ip6Address": "cafe:dead:d0d0::42",
"ipAddress": "10.2.3.4",
- "isPrimary": false,
"name": "origin1",
"port": 443,
"profileId": 1,
diff --git a/traffic_ops/app/db/migrations/20180606000000_remove_org_server_fqdn.sql b/traffic_ops/app/db/migrations/20180606000000_remove_org_server_fqdn.sql
new file mode 100644
index 0000000..967d1f6
--- /dev/null
+++ b/traffic_ops/app/db/migrations/20180606000000_remove_org_server_fqdn.sql
@@ -0,0 +1,46 @@
+/*
+
+ 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
+
+INSERT INTO origin (name, protocol, fqdn, port, deliveryservice, tenant, is_primary)
+SELECT
+d.xml_id,
+lower(split_part(d.org_server_fqdn, '://', 1))::origin_protocol,
+regexp_replace(d.org_server_fqdn, '(^https?://)|(:\d+$)', '', 'gi'),
+(SELECT (regexp_matches(d.org_server_fqdn, '(?<=:)\d+$'))[1]::bigint),
+d.id,
+d.tenant_id,
+TRUE
+FROM deliveryservice d
+WHERE d.org_server_fqdn IS NOT NULL;
+
+ALTER TABLE deliveryservice DROP COLUMN org_server_fqdn;
+
+-- +goose Down
+-- SQL section 'Down' is executed when this migration is rolled back
+
+ALTER TABLE deliveryservice ADD COLUMN org_server_fqdn text;
+
+UPDATE deliveryservice d
+SET org_server_fqdn = (
+ SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', o.port::text), ':')
+ FROM origin o
+ WHERE o.deliveryservice = d.id AND o.is_primary
+);
+
+DELETE FROM origin o
+WHERE o.is_primary;
diff --git a/traffic_ops/app/lib/API/Configs/ApacheTrafficServer.pm b/traffic_ops/app/lib/API/Configs/ApacheTrafficServer.pm
index 4d6cd4d..d33cefe 100755
--- a/traffic_ops/app/lib/API/Configs/ApacheTrafficServer.pm
+++ b/traffic_ops/app/lib/API/Configs/ApacheTrafficServer.pm
@@ -526,7 +526,10 @@ sub delivery_service_data_by_profile {
deliveryservice.routing_name,
deliveryservice.signing_algorithm,
deliveryservice.qstring_ignore,
- deliveryservice.org_server_fqdn,
+ (SELECT o.protocol::text || \'://\' || o.fqdn || rtrim(concat(\':\', o.port::text), \':\')
+ FROM origin o
+ WHERE o.deliveryservice = deliveryservice.id
+ AND o.is_primary) as org_server_fqdn,
deliveryservice.origin_shield,
regex.pattern AS pattern,
retype.name AS re_type,
@@ -2237,7 +2240,7 @@ sub cachegroup_profiles {
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 $org_uri = URI->new( $ds_row->deliveryservice->org_server_fqdn );
+ my $org_uri = URI->new( UI::DeliveryService::compute_org_server_fqdn($self, $ds_row->deliveryservice->id) );
push( @{ $deliveryservices->{ $org_uri->host } }, $row );
}
}
diff --git a/traffic_ops/app/lib/API/Deliveryservice.pm b/traffic_ops/app/lib/API/Deliveryservice.pm
index 9793e25..d8bc37a 100644
--- a/traffic_ops/app/lib/API/Deliveryservice.pm
+++ b/traffic_ops/app/lib/API/Deliveryservice.pm
@@ -138,7 +138,7 @@ sub index {
"missLat" => defined( $row->miss_lat ) ? 0.0 + $row->miss_lat : undef,
"missLong" => defined( $row->miss_long ) ? 0.0 + $row->miss_long : undef,
"multiSiteOrigin" => \$row->multi_site_origin,
- "orgServerFqdn" => $row->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $row->id),
"originShield" => $row->origin_shield,
"profileId" => defined( $row->profile ) ? $row->profile->id : undef,
"profileName" => defined( $row->profile ) ? $row->profile->name : undef,
@@ -262,7 +262,7 @@ sub show {
"missLat" => defined( $row->miss_lat ) ? 0.0 + $row->miss_lat : undef,
"missLong" => defined( $row->miss_long ) ? 0.0 + $row->miss_long : undef,
"multiSiteOrigin" => \$row->multi_site_origin,
- "orgServerFqdn" => $row->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $row->id),
"originShield" => $row->origin_shield,
"profileId" => defined( $row->profile ) ? $row->profile->id : undef,
"profileName" => defined( $row->profile ) ? $row->profile->name : undef,
@@ -376,7 +376,6 @@ sub update {
miss_lat => $params->{missLat},
miss_long => $params->{missLong},
multi_site_origin => $params->{multiSiteOrigin},
- org_server_fqdn => $params->{orgServerFqdn},
origin_shield => $params->{originShield},
profile => $params->{profileId},
protocol => $params->{protocol},
@@ -413,6 +412,21 @@ sub update {
my $rs = $ds->update($values);
if ($rs) {
+ # find this DS's primary Origin and update it too
+ my $origin_rs = $self->db->resultset('Origin')->find( { deliveryservice => $id, is_primary => 1 } );
+ my $origin = UI::DeliveryService::get_primary_origin_from_deliveryservice($id, $values, $params->{orgServerFqdn});
+ if ( defined( $origin ) && defined( $origin_rs ) ) {
+ $origin_rs->update($origin);
+ &log( $self, "Updated primary origin [ '" . $origin_rs->name . "' ] with id: " . $origin_rs->id, "APICHANGE" );
+ } elsif ( defined( $origin ) && !defined( $origin_rs ) ) {
+ $origin_rs = $self->db->resultset('Origin')->create($origin)->insert();
+ &log( $self, "Created primary origin [ '" . $origin_rs->name . "' ] with id: " . $origin_rs->id, "APICHANGE" );
+ } elsif ( !defined( $origin ) && defined( $origin_rs ) ) {
+ my $name = $origin_rs->name;
+ $origin_rs->delete();
+ &log( $self, "Deleted primary origin [ '" . $name . "' ] ", "APICHANGE" );
+ }
+
# create location parameters for header_rewrite*, regex_remap* and cacheurl* config files if necessary
&UI::DeliveryService::header_rewrite( $self, $rs->id, $values->{profileId}, $values->{xmlId}, $values->{edgeHeaderRewrite}, "edge" );
&UI::DeliveryService::header_rewrite( $self, $rs->id, $values->{profileId}, $values->{xmlId}, $values->{midHeaderRewrite}, "mid" );
@@ -480,7 +494,7 @@ sub update {
"missLat" => defined($rs->miss_lat) ? 0.0 + $rs->miss_lat : undef,
"missLong" => defined($rs->miss_long) ? 0.0 + $rs->miss_long : undef,
"multiSiteOrigin" => $rs->multi_site_origin,
- "orgServerFqdn" => $rs->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $rs->id),
"originShield" => $rs->origin_shield,
"profileId" => defined($rs->profile) ? $rs->profile->id : undef,
"profileName" => defined($rs->profile) ? $rs->profile->name : undef,
@@ -614,7 +628,7 @@ sub safe_update {
"missLat" => defined($rs->miss_lat) ? 0.0 + $rs->miss_lat : undef,
"missLong" => defined($rs->miss_long) ? 0.0 + $rs->miss_long : undef,
"multiSiteOrigin" => $rs->multi_site_origin,
- "orgServerFqdn" => $rs->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $rs->id),
"originShield" => $rs->origin_shield,
"profileId" => defined($rs->profile) ? $rs->profile->id : undef,
"profileName" => defined($rs->profile) ? $rs->profile->name : undef,
@@ -719,7 +733,6 @@ sub create {
miss_lat => $params->{missLat},
miss_long => $params->{missLong},
multi_site_origin => $params->{multiSiteOrigin},
- org_server_fqdn => $params->{orgServerFqdn},
origin_shield => $params->{originShield},
profile => $params->{profileId},
protocol => $params->{protocol},
@@ -756,6 +769,12 @@ sub create {
&log( $self, "Created delivery service [ '" . $insert->xml_id . "' ] with id: " . $insert->id, "APICHANGE" );
+ my $origin = UI::DeliveryService::get_primary_origin_from_deliveryservice($insert->id, $values, $params->{orgServerFqdn});
+ if (defined( $origin )) {
+ my $origin_rs = $self->db->resultset('Origin')->create($origin)->insert();
+ &log( $self, "Created origin [ '" . $origin_rs->name . "' ] with id: " . $origin_rs->id, "APICHANGE" );
+ }
+
# create location parameters for header_rewrite*, regex_remap* and cacheurl* config files if necessary
&UI::DeliveryService::header_rewrite( $self, $insert->id, $values->{id}, $values->{xml_id}, $values->{edge_header_rewrite}, "edge" );
&UI::DeliveryService::header_rewrite( $self, $insert->id, $values->{profile_id}, $values->{xml_id}, $values->{mid_header_rewrite}, "mid" );
@@ -834,7 +853,7 @@ sub create {
"missLat" => defined($insert->miss_lat) ? 0.0 + $insert->miss_lat : undef,
"missLong" => defined($insert->miss_long) ? 0.0 + $insert->miss_long : undef,
"multiSiteOrigin" => $insert->multi_site_origin,
- "orgServerFqdn" => $insert->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $insert->id),
"originShield" => $insert->origin_shield,
"profileId" => defined($insert->profile) ? $insert->profile->id : undef,
"profileName" => defined($insert->profile) ? $insert->profile->name : undef,
@@ -1027,7 +1046,7 @@ sub get_deliveryservices_by_serverId {
"missLat" => defined( $row->miss_lat ) ? 0.0 + $row->miss_lat : undef,
"missLong" => defined( $row->miss_long ) ? 0.0 + $row->miss_long : undef,
"multiSiteOrigin" => \$row->multi_site_origin,
- "orgServerFqdn" => $row->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $row->id),
"originShield" => $row->origin_shield,
"profileId" => defined( $row->profile ) ? $row->profile->id : undef,
"profileName" => defined( $row->profile ) ? $row->profile->name : undef,
@@ -1128,7 +1147,7 @@ sub get_deliveryservices_by_userId {
"missLat" => defined( $row->miss_lat ) ? 0.0 + $row->miss_lat : undef,
"missLong" => defined( $row->miss_long ) ? 0.0 + $row->miss_long : undef,
"multiSiteOrigin" => \$row->multi_site_origin,
- "orgServerFqdn" => $row->org_server_fqdn,
+ "orgServerFqdn" => UI::DeliveryService::compute_org_server_fqdn($self, $row->id),
"originShield" => $row->origin_shield,
"profileId" => defined( $row->profile ) ? $row->profile->id : undef,
"profileName" => defined( $row->profile ) ? $row->profile->name : undef,
diff --git a/traffic_ops/app/lib/Fixtures/Deliveryservice.pm b/traffic_ops/app/lib/Fixtures/Deliveryservice.pm
index 59f6cf4..e087be9 100644
--- a/traffic_ops/app/lib/Fixtures/Deliveryservice.pm
+++ b/traffic_ops/app/lib/Fixtures/Deliveryservice.pm
@@ -44,7 +44,6 @@ my %definition_for = (
long_desc_2 => 'test-ds1 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds1.edge',
info_url => 'http://test-ds1.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -86,7 +85,6 @@ my %definition_for = (
long_desc_2 => 'test-ds2 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds2.edge',
info_url => 'http://test-ds2.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -128,7 +126,6 @@ my %definition_for = (
long_desc_2 => 'test-ds3 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds3.edge',
info_url => 'http://test-ds3.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -170,7 +167,6 @@ my %definition_for = (
long_desc_2 => 'test-ds4 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds4.edge',
info_url => 'http://test-ds4.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -212,7 +208,6 @@ my %definition_for = (
long_desc_2 => 'test-ds5 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds5.edge',
info_url => 'http://test-ds5.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -254,7 +249,6 @@ my %definition_for = (
long_desc_2 => 'test-ds6 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds6.edge',
info_url => 'http://test-ds6.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -295,7 +289,6 @@ my %definition_for = (
long_desc_2 => 'steering-ds1 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://steering-ds1.edge',
info_url => 'http://steering-ds1.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -335,7 +328,6 @@ my %definition_for = (
long_desc_2 => 'steering-ds2 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://steering-ds2.edge',
info_url => 'http://steering-ds2.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -375,7 +367,6 @@ my %definition_for = (
long_desc_2 => 'new-steering-ds long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://new-steering-ds.edge',
info_url => 'http://new-steering-ds.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -415,7 +406,6 @@ my %definition_for = (
long_desc_2 => 'target-ds1 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://target-ds1.edge',
info_url => 'http://target-ds1.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -455,7 +445,6 @@ my %definition_for = (
long_desc_2 => 'target-ds2 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://target-ds2.edge',
info_url => 'http://target-ds2.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -495,7 +484,6 @@ my %definition_for = (
long_desc_2 => 'target-ds3 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://target-ds3.edge',
info_url => 'http://target-ds3.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -535,7 +523,6 @@ my %definition_for = (
long_desc_2 => 'target-ds4 long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://target-ds4.edge',
info_url => 'http://target-ds4.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -576,7 +563,6 @@ my %definition_for = (
long_desc_2 => 'test-ds1-root long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://test-ds1-root.edge',
info_url => 'http://test-ds1-root.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
@@ -618,7 +604,6 @@ my %definition_for = (
long_desc_2 => 'foo.bar long_desc_2',
max_dns_answers => 0,
protocol => 0,
- org_server_fqdn => 'http://foo.bar.edge',
info_url => 'http://foo.bar.edge/info_url.html',
miss_lat => '41.881944',
miss_long => '-87.627778',
diff --git a/traffic_ops/app/lib/Fixtures/Integration/Deliveryservice.pm b/traffic_ops/app/lib/Fixtures/Integration/Deliveryservice.pm
index 678df65..5acc84d 100644
--- a/traffic_ops/app/lib/Fixtures/Integration/Deliveryservice.pm
+++ b/traffic_ops/app/lib/Fixtures/Integration/Deliveryservice.pm
@@ -70,7 +70,6 @@ my %definition_for = (
cdn_id => '2',
dns_bypass_ttl => undef,
initial_dispersion => '1',
- org_server_fqdn => 'http://cdl.origin.kabletown.net',
range_request_handling => '0',
signing_algorithm => 'url_sig',
dns_bypass_ip => '',
@@ -117,7 +116,6 @@ my %definition_for = (
display_name => 'games-c1',
http_bypass_fqdn => '',
info_url => 'http://games.info.kabletown.net',
- org_server_fqdn => 'http://games.origin.kabletown.net',
ccr_dns_ttl => '3600',
dns_bypass_ip6 => undef,
last_updated => '2015-12-10 15:44:37',
@@ -150,7 +148,6 @@ my %definition_for = (
deep_caching_type => 'NEVER',
routing_name => 'foo',
last_updated => '2015-12-10 15:44:37',
- org_server_fqdn => 'http://images.origin.kabletown.net',
tr_response_headers => undef,
cacheurl => undef,
check_path => '/crossdomain.xml',
@@ -224,7 +221,6 @@ my %definition_for = (
edge_header_rewrite => 'cond %{REMAP_PSEUDO_HOOK} __RETURN__ set-config proxy.config.http.transaction_active_timeout_out 5 [L]',
global_max_mbps => '0',
ssl_key_version => '0',
- org_server_fqdn => 'http://movies.origin.kabletown.net',
range_request_handling => '0',
regex_remap => undef,
miss_long => '-87.627778',
@@ -278,7 +274,6 @@ my %definition_for = (
check_path => '/crossdomain.xml',
dns_bypass_ip => '',
tr_response_headers => undef,
- org_server_fqdn => 'http://movies.origin.kabletown.net',
geo_limit => '0',
long_desc_2 => 'test-ds1 long_desc_2',
edge_header_rewrite => undef,
@@ -322,7 +317,6 @@ my %definition_for = (
fq_pacing_rate => '0',
http_bypass_fqdn => '',
miss_long => '-87.627778',
- org_server_fqdn => 'https://games.origin.kabletown.net',
multi_site_origin => undef,
cacheurl => undef,
dns_bypass_ip => '',
@@ -374,7 +368,6 @@ my %definition_for = (
fq_pacing_rate => '0',
initial_dispersion => '1',
multi_site_origin => undef,
- org_server_fqdn => 'http://national-tv.origin.kabletown.net',
signing_algorithm => undef,
display_name => 'tv-nat-c2',
dns_bypass_ip6 => undef,
@@ -433,7 +426,6 @@ my %definition_for = (
regex_remap => undef,
remap_text => undef,
miss_long => '-87.627778',
- org_server_fqdn => 'http://cc.origin.kabletown.net',
display_name => 'tv-nocache-c2',
qstring_ignore => '0',
dns_bypass_ip6 => undef,
diff --git a/traffic_ops/app/lib/Fixtures/Integration/Origin.pm b/traffic_ops/app/lib/Fixtures/Integration/Origin.pm
new file mode 100644
index 0000000..5487506
--- /dev/null
+++ b/traffic_ops/app/lib/Fixtures/Integration/Origin.pm
@@ -0,0 +1,186 @@
+package Fixtures::Integration::Origin;
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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 Moose;
+extends 'DBIx::Class::EasyFixture';
+use namespace::autoclean;
+
+my %definition_for = (
+ ## id => 1
+ '0' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin1',
+ fqdn => 'cdl.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 1,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 2
+ '1' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin2',
+ fqdn => 'games.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 2,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 3
+ '2' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin3',
+ fqdn => 'images.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 3,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 4
+ '3' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin4',
+ fqdn => 'movies.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 4,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 5
+ '4' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin5',
+ fqdn => 'movies.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 5,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 6
+ '5' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin6',
+ fqdn => 'games.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 6,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 7
+ '6' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin7',
+ fqdn => 'national-tv.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 7,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ ## id => 8
+ '7' => {
+ new => 'Origin',
+ using => {
+ name => 'test-origin8',
+ fqdn => 'cc.origin.kabletown.net',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 8,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+);
+
+sub name {
+ return "Origin";
+}
+
+sub get_definition {
+ my ( $self, $name ) = @_;
+ return $definition_for{$name};
+}
+
+sub all_fixture_names {
+ # sort by db name to guarantee insertion order
+ return (sort { $definition_for{$a}{using}{name} cmp $definition_for{$b}{using}{name} } keys %definition_for);
+}
+__PACKAGE__->meta->make_immutable;
+1;
diff --git a/traffic_ops/app/lib/Fixtures/Origin.pm b/traffic_ops/app/lib/Fixtures/Origin.pm
new file mode 100644
index 0000000..baf60ee
--- /dev/null
+++ b/traffic_ops/app/lib/Fixtures/Origin.pm
@@ -0,0 +1,307 @@
+package Fixtures::Origin;
+
+#
+#
+# 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 Moose;
+extends 'DBIx::Class::EasyFixture';
+use namespace::autoclean;
+
+my %definition_for = (
+ origin_cdn1 => {
+ new => 'Origin',
+ using => {
+ id => 100,
+ name => 'test-origin1',
+ fqdn => 'test-ds1.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 100,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_cdn2 => {
+ new => 'Origin',
+ using => {
+ id => 200,
+ name => 'test-origin2',
+ fqdn => 'test-ds2.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 200,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_cdn3 => {
+ new => 'Origin',
+ using => {
+ id => 300,
+ name => 'test-origin3',
+ fqdn => 'test-ds3.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 300,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_cdn4 => {
+ new => 'Origin',
+ using => {
+ id => 400,
+ name => 'test-origin4',
+ fqdn => 'test-ds4.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 400,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_dns => {
+ new => 'Origin',
+ using => {
+ id => 500,
+ name => 'test-origin5',
+ fqdn => 'test-ds5.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 500,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_http_no_cache => {
+ new => 'Origin',
+ using => {
+ id => 600,
+ name => 'test-origin6',
+ fqdn => 'test-ds6.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 600,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ steering_origin1 => {
+ new => 'Origin',
+ using => {
+ id => 700,
+ name => 'test-origin7',
+ fqdn => 'steering-ds1.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 700,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ steering_origin2 => {
+ new => 'Origin',
+ using => {
+ id => 800,
+ name => 'test-origin8',
+ fqdn => 'steering-ds2.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 800,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ new_origin_steering => {
+ new => 'Origin',
+ using => {
+ id => 900,
+ name => 'test-origin9',
+ fqdn => 'new-steering-ds.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 900,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ target_origin1 => {
+ new => 'Origin',
+ using => {
+ id => 1000,
+ name => 'test-origin10',
+ fqdn => 'target-ds1.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 1000,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ target_origin2 => {
+ new => 'Origin',
+ using => {
+ id => 1100,
+ name => 'test-origin11',
+ fqdn => 'target-ds2.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 1100,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ target_origin3 => {
+ new => 'Origin',
+ using => {
+ id => 1200,
+ name => 'test-origin12',
+ fqdn => 'target-ds3.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 1200,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ target_origin4 => {
+ new => 'Origin',
+ using => {
+ id => 1300,
+ name => 'test-origin13',
+ fqdn => 'target-ds4.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 1300,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+ origin_cdn1_root => {
+ new => 'Origin',
+ using => {
+ id => 2100,
+ name => 'test-origin14',
+ fqdn => 'test-ds1-root.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 2100,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => 10**9,
+ },
+ },
+ origin_period1 => {
+ new => 'Origin',
+ using => {
+ id => 2200,
+ name => 'test-origin15',
+ fqdn => 'foo.bar.edge',
+ protocol => 'http',
+ is_primary => 1,
+ port => undef,
+ ip_address => undef,
+ ip6_address => undef,
+ deliveryservice => 2200,
+ coordinate => undef,
+ profile => undef,
+ cachegroup => undef,
+ tenant => undef,
+ },
+ },
+
+);
+
+sub get_definition {
+ my ( $self, $name ) = @_;
+ return $definition_for{$name};
+}
+
+sub all_fixture_names {
+ # sort by db id to guarantee insertion order
+ return (sort { $definition_for{$a}{using}{id} cmp $definition_for{$b}{using}{id} } keys %definition_for);
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
diff --git a/traffic_ops/app/lib/MojoPlugins/Job.pm b/traffic_ops/app/lib/MojoPlugins/Job.pm
index 1ec0ed0..1f7634c 100755
--- a/traffic_ops/app/lib/MojoPlugins/Job.pm
+++ b/traffic_ops/app/lib/MojoPlugins/Job.pm
@@ -180,7 +180,7 @@ sub register {
}
my $start_time_gmt = strftime( "%Y-%m-%d %H:%M:%S", gmtime($start_time) );
my $entered_time = strftime( "%Y-%m-%d %H:%M:%S", gmtime() );
- my $org_server_fqdn = $self->db->resultset("Deliveryservice")->search( { id => $ds_id } )->get_column('org_server_fqdn')->single();
+ my $org_server_fqdn = UI::DeliveryService::compute_org_server_fqdn($self, $ds_id);
my $tm_user_id = $self->db->resultset('TmUser')->search( { username => $self->current_user()->{username} } )->get_column('id')->single();
@@ -227,7 +227,7 @@ sub register {
my ( $scheme, $asset_hostname, $path, $query, $fragment ) = $asset =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
while ( my $ds_row = $rs_ds->next ) {
- my $org_server_fqdn = $ds_row->org_server_fqdn;
+ my $org_server_fqdn = UI::DeliveryService::compute_org_server_fqdn($self, $ds_row->id);
if ( defined($org_server_fqdn) && $asset =~ /$org_server_fqdn/ ) {
return 1; # Success
}
diff --git a/traffic_ops/app/lib/Schema/Result/Cachegroup.pm b/traffic_ops/app/lib/Schema/Result/Cachegroup.pm
index a93c039..453779f 100644
--- a/traffic_ops/app/lib/Schema/Result/Cachegroup.pm
+++ b/traffic_ops/app/lib/Schema/Result/Cachegroup.pm
@@ -72,7 +72,7 @@ __PACKAGE__->table("cachegroup");
data_type: 'timestamp with time zone'
default_value: current_timestamp
- is_nullable: 1
+ is_nullable: 0
original: {default_value => \"now()"}
=head2 fallback_to_closest
@@ -109,7 +109,7 @@ __PACKAGE__->add_columns(
{
data_type => "timestamp with time zone",
default_value => \"current_timestamp",
- is_nullable => 1,
+ is_nullable => 0,
original => { default_value => \"now()" },
},
"fallback_to_closest",
@@ -132,7 +132,7 @@ __PACKAGE__->set_primary_key("id", "type");
=head1 UNIQUE CONSTRAINTS
-=head2 C<idx_54252_cg_name_unique>
+=head2 C<idx_140208_cg_name_unique>
=over 4
@@ -142,9 +142,9 @@ __PACKAGE__->set_primary_key("id", "type");
=cut
-__PACKAGE__->add_unique_constraint("idx_54252_cg_name_unique", ["name"]);
+__PACKAGE__->add_unique_constraint("idx_140208_cg_name_unique", ["name"]);
-=head2 C<idx_54252_cg_short_unique>
+=head2 C<idx_140208_cg_short_unique>
=over 4
@@ -154,9 +154,9 @@ __PACKAGE__->add_unique_constraint("idx_54252_cg_name_unique", ["name"]);
=cut
-__PACKAGE__->add_unique_constraint("idx_54252_cg_short_unique", ["short_name"]);
+__PACKAGE__->add_unique_constraint("idx_140208_cg_short_unique", ["short_name"]);
-=head2 C<idx_54252_lo_id_unique>
+=head2 C<idx_140208_lo_id_unique>
=over 4
@@ -166,7 +166,7 @@ __PACKAGE__->add_unique_constraint("idx_54252_cg_short_unique", ["short_name"]);
=cut
-__PACKAGE__->add_unique_constraint("idx_54252_lo_id_unique", ["id"]);
+__PACKAGE__->add_unique_constraint("idx_140208_lo_id_unique", ["id"]);
=head1 RELATIONS
@@ -260,6 +260,21 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
+=head2 origins
+
+Type: has_many
+
+Related object: L<Schema::Result::Origin>
+
+=cut
+
+__PACKAGE__->has_many(
+ "origins",
+ "Schema::Result::Origin",
+ { "foreign.cachegroup" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
=head2 parent_cachegroup
Type: belongs_to
@@ -346,8 +361,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07046 @ 2016-11-18 22:45:19
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lU7dUVFuoTyhpC7x7BGaDg
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-15 16:06:00
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2EeelbrXDdiyrV9BXGuIeA
# You can replace this text with custom code or comments, and it will be preserved on regeneration
#
diff --git a/traffic_ops/app/lib/Schema/Result/Coordinate.pm b/traffic_ops/app/lib/Schema/Result/Coordinate.pm
new file mode 100644
index 0000000..7463079
--- /dev/null
+++ b/traffic_ops/app/lib/Schema/Result/Coordinate.pm
@@ -0,0 +1,131 @@
+use utf8;
+package Schema::Result::Coordinate;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Schema::Result::Coordinate
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 TABLE: C<coordinate>
+
+=cut
+
+__PACKAGE__->table("coordinate");
+
+=head1 ACCESSORS
+
+=head2 id
+
+ data_type: 'bigint'
+ is_auto_increment: 1
+ is_nullable: 0
+ sequence: 'coordinate_id_seq'
+
+=head2 name
+
+ data_type: 'text'
+ is_nullable: 0
+
+=head2 latitude
+
+ data_type: 'numeric'
+ default_value: 0.0
+ is_nullable: 0
+
+=head2 longitude
+
+ data_type: 'numeric'
+ default_value: 0.0
+ is_nullable: 0
+
+=head2 last_updated
+
+ data_type: 'timestamp with time zone'
+ default_value: current_timestamp
+ is_nullable: 0
+ original: {default_value => \"now()"}
+
+=cut
+
+__PACKAGE__->add_columns(
+ "id",
+ {
+ data_type => "bigint",
+ is_auto_increment => 1,
+ is_nullable => 0,
+ sequence => "coordinate_id_seq",
+ },
+ "name",
+ { data_type => "text", is_nullable => 0 },
+ "latitude",
+ { data_type => "numeric", default_value => "0.0", is_nullable => 0 },
+ "longitude",
+ { data_type => "numeric", default_value => "0.0", is_nullable => 0 },
+ "last_updated",
+ {
+ data_type => "timestamp with time zone",
+ default_value => \"current_timestamp",
+ is_nullable => 0,
+ original => { default_value => \"now()" },
+ },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<coordinate_name_key>
+
+=over 4
+
+=item * L</name>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("coordinate_name_key", ["name"]);
+
+=head1 RELATIONS
+
+=head2 origins
+
+Type: has_many
+
+Related object: L<Schema::Result::Origin>
+
+=cut
+
+__PACKAGE__->has_many(
+ "origins",
+ "Schema::Result::Origin",
+ { "foreign.coordinate" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-15 16:06:00
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:FZ64Zkbh+B6CECd1k/h66w
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForDomainList.pm b/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForDomainList.pm
index bb0f231..bc14e24 100644
--- a/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForDomainList.pm
+++ b/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForDomainList.pm
@@ -45,7 +45,10 @@ SELECT
deliveryservice.routing_name,
deliveryservice.signing_algorithm,
deliveryservice.qstring_ignore,
- deliveryservice.org_server_fqdn,
+ (SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', o.port::text), ':')
+ FROM origin o
+ WHERE o.deliveryservice = deliveryservice.id
+ AND o.is_primary) as org_server_fqdn,
deliveryservice.multi_site_origin,
deliveryservice.range_request_handling,
deliveryservice.fq_pacing_rate,
diff --git a/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForServerList.pm b/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForServerList.pm
index f190d33..ce32594 100644
--- a/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForServerList.pm
+++ b/traffic_ops/app/lib/Schema/Result/DeliveryServiceInfoForServerList.pm
@@ -45,7 +45,10 @@ SELECT
deliveryservice.routing_name AS routing_name,
deliveryservice.signing_algorithm AS signing_algorithm,
deliveryservice.qstring_ignore AS qstring_ignore,
- deliveryservice.org_server_fqdn as org_server_fqdn,
+ (SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', o.port::text), ':')
+ FROM origin o
+ WHERE o.deliveryservice = deliveryservice.id
+ AND o.is_primary) as org_server_fqdn,
deliveryservice.multi_site_origin as multi_site_origin,
deliveryservice.range_request_handling as range_request_handling,
deliveryservice.fq_pacing_rate as fq_pacing_rate,
diff --git a/traffic_ops/app/lib/Schema/Result/Deliveryservice.pm b/traffic_ops/app/lib/Schema/Result/Deliveryservice.pm
index dab1cce..94d4b9c 100644
--- a/traffic_ops/app/lib/Schema/Result/Deliveryservice.pm
+++ b/traffic_ops/app/lib/Schema/Result/Deliveryservice.pm
@@ -87,11 +87,6 @@ __PACKAGE__->table("deliveryservice");
data_type: 'bigint'
is_nullable: 1
-=head2 org_server_fqdn
-
- data_type: 'text'
- is_nullable: 1
-
=head2 type
data_type: 'bigint'
@@ -170,7 +165,7 @@ __PACKAGE__->table("deliveryservice");
data_type: 'timestamp with time zone'
default_value: current_timestamp
- is_nullable: 1
+ is_nullable: 0
original: {default_value => \"now()"}
=head2 protocol
@@ -349,8 +344,6 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 1 },
"dns_bypass_ttl",
{ data_type => "bigint", is_nullable => 1 },
- "org_server_fqdn",
- { data_type => "text", is_nullable => 1 },
"type",
{ data_type => "bigint", is_foreign_key => 1, is_nullable => 0 },
"profile",
@@ -383,7 +376,7 @@ __PACKAGE__->add_columns(
{
data_type => "timestamp with time zone",
default_value => \"current_timestamp",
- is_nullable => 1,
+ is_nullable => 0,
original => { default_value => \"now()" },
},
"protocol",
@@ -464,7 +457,7 @@ __PACKAGE__->set_primary_key("id", "type");
=head1 UNIQUE CONSTRAINTS
-=head2 C<idx_89502_ds_id_unique>
+=head2 C<idx_140234_ds_id_unique>
=over 4
@@ -474,9 +467,9 @@ __PACKAGE__->set_primary_key("id", "type");
=cut
-__PACKAGE__->add_unique_constraint("idx_89502_ds_id_unique", ["id"]);
+__PACKAGE__->add_unique_constraint("idx_140234_ds_id_unique", ["id"]);
-=head2 C<idx_89502_ds_name_unique>
+=head2 C<idx_140234_ds_name_unique>
=over 4
@@ -486,7 +479,7 @@ __PACKAGE__->add_unique_constraint("idx_89502_ds_id_unique", ["id"]);
=cut
-__PACKAGE__->add_unique_constraint("idx_89502_ds_name_unique", ["xml_id"]);
+__PACKAGE__->add_unique_constraint("idx_140234_ds_name_unique", ["xml_id"]);
=head1 RELATIONS
@@ -580,6 +573,21 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
+=head2 origins
+
+Type: has_many
+
+Related object: L<Schema::Result::Origin>
+
+=cut
+
+__PACKAGE__->has_many(
+ "origins",
+ "Schema::Result::Origin",
+ { "foreign.deliveryservice" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
=head2 profile
Type: belongs_to
@@ -681,8 +689,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07047 @ 2018-02-28 21:54:35
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3ETqht/3FTxKgD/YuRf3Bg
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-17 16:24:12
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Yjz2V+duaN88QPILxLqoHg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
#
diff --git a/traffic_ops/app/lib/Schema/Result/Origin.pm b/traffic_ops/app/lib/Schema/Result/Origin.pm
new file mode 100644
index 0000000..6c0126e
--- /dev/null
+++ b/traffic_ops/app/lib/Schema/Result/Origin.pm
@@ -0,0 +1,285 @@
+use utf8;
+package Schema::Result::Origin;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Schema::Result::Origin
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 TABLE: C<origin>
+
+=cut
+
+__PACKAGE__->table("origin");
+
+=head1 ACCESSORS
+
+=head2 id
+
+ data_type: 'bigint'
+ is_auto_increment: 1
+ is_nullable: 0
+ sequence: 'origin_id_seq'
+
+=head2 name
+
+ data_type: 'text'
+ is_nullable: 0
+
+=head2 fqdn
+
+ data_type: 'text'
+ is_nullable: 0
+
+=head2 protocol
+
+ data_type: 'enum'
+ default_value: 'http'
+ extra: {custom_type_name => "origin_protocol",list => ["http","https"]}
+ is_nullable: 0
+
+=head2 is_primary
+
+ data_type: 'boolean'
+ default_value: false
+ is_nullable: 0
+
+=head2 port
+
+ data_type: 'bigint'
+ is_nullable: 1
+
+=head2 ip_address
+
+ data_type: 'text'
+ is_nullable: 1
+
+=head2 ip6_address
+
+ data_type: 'text'
+ is_nullable: 1
+
+=head2 deliveryservice
+
+ data_type: 'bigint'
+ is_foreign_key: 1
+ is_nullable: 0
+
+=head2 coordinate
+
+ data_type: 'bigint'
+ is_foreign_key: 1
+ is_nullable: 1
+
+=head2 profile
+
+ data_type: 'bigint'
+ is_foreign_key: 1
+ is_nullable: 1
+
+=head2 cachegroup
+
+ data_type: 'bigint'
+ is_foreign_key: 1
+ is_nullable: 1
+
+=head2 tenant
+
+ data_type: 'bigint'
+ is_foreign_key: 1
+ is_nullable: 1
+
+=head2 last_updated
+
+ data_type: 'timestamp with time zone'
+ default_value: current_timestamp
+ is_nullable: 0
+ original: {default_value => \"now()"}
+
+=cut
+
+__PACKAGE__->add_columns(
+ "id",
+ {
+ data_type => "bigint",
+ is_auto_increment => 1,
+ is_nullable => 0,
+ sequence => "origin_id_seq",
+ },
+ "name",
+ { data_type => "text", is_nullable => 0 },
+ "fqdn",
+ { data_type => "text", is_nullable => 0 },
+ "protocol",
+ {
+ data_type => "enum",
+ default_value => "http",
+ extra => { custom_type_name => "origin_protocol", list => ["http", "https"] },
+ is_nullable => 0,
+ },
+ "is_primary",
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "port",
+ { data_type => "bigint", is_nullable => 1 },
+ "ip_address",
+ { data_type => "text", is_nullable => 1 },
+ "ip6_address",
+ { data_type => "text", is_nullable => 1 },
+ "deliveryservice",
+ { data_type => "bigint", is_foreign_key => 1, is_nullable => 0 },
+ "coordinate",
+ { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 },
+ "profile",
+ { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 },
+ "cachegroup",
+ { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 },
+ "tenant",
+ { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 },
+ "last_updated",
+ {
+ data_type => "timestamp with time zone",
+ default_value => \"current_timestamp",
+ is_nullable => 0,
+ original => { default_value => \"now()" },
+ },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<origin_name_key>
+
+=over 4
+
+=item * L</name>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("origin_name_key", ["name"]);
+
+=head1 RELATIONS
+
+=head2 cachegroup
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Cachegroup>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "cachegroup",
+ "Schema::Result::Cachegroup",
+ { id => "cachegroup" },
+ {
+ is_deferrable => 0,
+ join_type => "LEFT",
+ on_delete => "RESTRICT",
+ on_update => "NO ACTION",
+ },
+);
+
+=head2 coordinate
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Coordinate>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "coordinate",
+ "Schema::Result::Coordinate",
+ { id => "coordinate" },
+ {
+ is_deferrable => 0,
+ join_type => "LEFT",
+ on_delete => "RESTRICT",
+ on_update => "NO ACTION",
+ },
+);
+
+=head2 deliveryservice
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Deliveryservice>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "deliveryservice",
+ "Schema::Result::Deliveryservice",
+ { id => "deliveryservice" },
+ { is_deferrable => 0, on_delete => "CASCADE", on_update => "NO ACTION" },
+);
+
+=head2 profile
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Profile>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "profile",
+ "Schema::Result::Profile",
+ { id => "profile" },
+ {
+ is_deferrable => 0,
+ join_type => "LEFT",
+ on_delete => "RESTRICT",
+ on_update => "NO ACTION",
+ },
+);
+
+=head2 tenant
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Tenant>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "tenant",
+ "Schema::Result::Tenant",
+ { id => "tenant" },
+ {
+ is_deferrable => 0,
+ join_type => "LEFT",
+ on_delete => "RESTRICT",
+ on_update => "NO ACTION",
+ },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-15 16:06:00
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:EFdWsJg/ANV/vUHBHfK0iA
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/traffic_ops/app/lib/Schema/Result/Profile.pm b/traffic_ops/app/lib/Schema/Result/Profile.pm
index 998a8fa..c5deafe 100644
--- a/traffic_ops/app/lib/Schema/Result/Profile.pm
+++ b/traffic_ops/app/lib/Schema/Result/Profile.pm
@@ -44,7 +44,7 @@ __PACKAGE__->table("profile");
data_type: 'timestamp with time zone'
default_value: current_timestamp
- is_nullable: 1
+ is_nullable: 0
original: {default_value => \"now()"}
=head2 type
@@ -83,7 +83,7 @@ __PACKAGE__->add_columns(
{
data_type => "timestamp with time zone",
default_value => \"current_timestamp",
- is_nullable => 1,
+ is_nullable => 0,
original => { default_value => \"now()" },
},
"type",
@@ -179,6 +179,21 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
+=head2 origins
+
+Type: has_many
+
+Related object: L<Schema::Result::Origin>
+
+=cut
+
+__PACKAGE__->has_many(
+ "origins",
+ "Schema::Result::Origin",
+ { "foreign.profile" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
=head2 profile_parameters
Type: has_many
@@ -210,8 +225,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07047 @ 2017-09-05 09:54:32
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BzUCSsUKInomx0bcvL5eAw
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-15 16:06:00
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:eX4sXLElEMpaA0xfHTv5lw
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/traffic_ops/app/lib/Schema/Result/Tenant.pm b/traffic_ops/app/lib/Schema/Result/Tenant.pm
index 646e2c9..27b1279 100644
--- a/traffic_ops/app/lib/Schema/Result/Tenant.pm
+++ b/traffic_ops/app/lib/Schema/Result/Tenant.pm
@@ -52,7 +52,7 @@ __PACKAGE__->table("tenant");
data_type: 'timestamp with time zone'
default_value: current_timestamp
- is_nullable: 1
+ is_nullable: 0
original: {default_value => \"now()"}
=cut
@@ -80,7 +80,7 @@ __PACKAGE__->add_columns(
{
data_type => "timestamp with time zone",
default_value => \"current_timestamp",
- is_nullable => 1,
+ is_nullable => 0,
original => { default_value => \"now()" },
},
);
@@ -128,6 +128,21 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
+=head2 origins
+
+Type: has_many
+
+Related object: L<Schema::Result::Origin>
+
+=cut
+
+__PACKAGE__->has_many(
+ "origins",
+ "Schema::Result::Origin",
+ { "foreign.tenant" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
=head2 parent
Type: belongs_to
@@ -179,8 +194,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-04-04 20:51:35
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7I7o08tTBHjshtXVypmOUw
+# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-05-15 16:06:00
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:fLrBvjW6JLyIRv59Qkrr+Q
# You can replace this text with custom code or comments, and it will be preserved on regeneration
#
diff --git a/traffic_ops/app/lib/Test/IntegrationTestHelper.pm b/traffic_ops/app/lib/Test/IntegrationTestHelper.pm
index e86166f..9213d68 100644
--- a/traffic_ops/app/lib/Test/IntegrationTestHelper.pm
+++ b/traffic_ops/app/lib/Test/IntegrationTestHelper.pm
@@ -45,6 +45,7 @@ use Fixtures::Integration::JobAgent;
use Fixtures::Integration::Job;
use Fixtures::Integration::JobStatus;
use Fixtures::Integration::Log;
+use Fixtures::Integration::Origin;
use Fixtures::Integration::Parameter;
use Fixtures::Integration::PhysLocation;
use Fixtures::Integration::ProfileParameter;
@@ -157,6 +158,7 @@ sub load_core_data {
$self->load_all_fixtures( Fixtures::Integration::Asn->new($schema_values) );
$self->load_all_fixtures( Fixtures::Integration::Server->new($schema_values) );
$self->load_all_fixtures( Fixtures::Integration::Deliveryservice->new($schema_values) );
+ $self->load_all_fixtures( Fixtures::Integration::Origin->new($schema_values) );
$self->load_all_fixtures( Fixtures::Integration::DeliveryserviceRegex->new($schema_values) );
$self->load_all_fixtures( Fixtures::Integration::DeliveryserviceServer->new($schema_values) );
$self->load_all_fixtures( Fixtures::Integration::ToExtension->new($schema_values) );
diff --git a/traffic_ops/app/lib/Test/TestHelper.pm b/traffic_ops/app/lib/Test/TestHelper.pm
index 6c38f32..388f181 100644
--- a/traffic_ops/app/lib/Test/TestHelper.pm
+++ b/traffic_ops/app/lib/Test/TestHelper.pm
@@ -29,6 +29,7 @@ use Schema;
use Utils::Tenant;
use Fixtures::Cdn;
use Fixtures::Deliveryservice;
+use Fixtures::Origin;
use Fixtures::DeliveryserviceTmuser;
use Fixtures::Asn;
use Fixtures::Cachegroup;
@@ -136,6 +137,7 @@ sub load_core_data {
$self->load_all_fixtures( Fixtures::Server->new($schema_values) );
$self->load_all_fixtures( Fixtures::Asn->new($schema_values) );
$self->load_all_fixtures( Fixtures::Deliveryservice->new($schema_values) );
+ $self->load_all_fixtures( Fixtures::Origin->new($schema_values) );
$self->load_all_fixtures( Fixtures::Regex->new($schema_values) );
$self->load_all_fixtures( Fixtures::DeliveryserviceRegex->new($schema_values) );
$self->load_all_fixtures( Fixtures::DeliveryserviceTmuser->new($schema_values) );
@@ -162,6 +164,7 @@ sub unload_core_data {
$self->teardown($schema, 'DeliveryserviceRegex');
$self->teardown($schema, 'Regex');
$self->teardown($schema, 'DeliveryserviceServer');
+ $self->teardown($schema, 'Origin');
$self->teardown($schema, 'Deliveryservice');
$self->teardown($schema, 'Server');
$self->teardown($schema, 'PhysLocation');
diff --git a/traffic_ops/app/lib/UI/Cdn.pm b/traffic_ops/app/lib/UI/Cdn.pm
index dd1cb92..72f2aea 100644
--- a/traffic_ops/app/lib/UI/Cdn.pm
+++ b/traffic_ops/app/lib/UI/Cdn.pm
@@ -475,7 +475,7 @@ sub adeliveryservice {
my $cdn_name = defined( $row->cdn_id ) ? $row->cdn->name : "";
# This will be undefined for 'Steering' delivery services
- my $org_server_fqdn = defined($row->org_server_fqdn) ? $row->org_server_fqdn : "";
+ my $org_server_fqdn = UI::DeliveryService::compute_org_server_fqdn($self, $row->id) // "";
my $ptext = defined($row->profile) ? $row->profile->name : "-";
my $line = [
diff --git a/traffic_ops/app/lib/UI/ConfigFiles.pm b/traffic_ops/app/lib/UI/ConfigFiles.pm
index ae1c937..90c4bd2 100644
--- a/traffic_ops/app/lib/UI/ConfigFiles.pm
+++ b/traffic_ops/app/lib/UI/ConfigFiles.pm
@@ -445,7 +445,7 @@ sub cachegroup_profiles {
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;
+ my $ds_domain = UI::DeliveryService::compute_org_server_fqdn($self, $ds_row->deliveryservice->id);
$ds_domain =~ s/https?:\/\/(.*)/$1/;
push( @{ $deliveryservices->{$ds_domain} }, $row );
}
diff --git a/traffic_ops/app/lib/UI/DeliveryService.pm b/traffic_ops/app/lib/UI/DeliveryService.pm
index a7e45a3..12417f5 100644
--- a/traffic_ops/app/lib/UI/DeliveryService.pm
+++ b/traffic_ops/app/lib/UI/DeliveryService.pm
@@ -58,11 +58,15 @@ sub edit {
my $server_count = $self->db->resultset('DeliveryserviceServer')->search( { deliveryservice => $id } )->count();
my $static_count = $self->db->resultset('Staticdnsentry')->search( { deliveryservice => $id } )->count();
+ my $origin = {};
+ $origin->{org_server_fqdn} = compute_org_server_fqdn($self, $id);
+
$self->stash_profile_selector('DS_PROFILE', defined($data->profile) ? $data->profile->id : undef);
$self->stash_cdn_selector($data->cdn->id);
&stash_role($self);
$self->stash(
ds => $data,
+ origin => $origin,
server_count => $server_count,
static_count => $static_count,
fbox_layout => 1,
@@ -73,6 +77,24 @@ sub edit {
);
}
+sub compute_org_server_fqdn {
+ my $self = shift;
+ my $ds_id = shift;
+
+ my $origin = $self->db->resultset('Origin')->search( { deliveryservice => $ds_id, is_primary => 1 } )->single();
+ if (!defined( $origin )) {
+ return undef;
+ }
+
+ my $protocol = $origin->protocol;
+ my $fqdn = $origin->fqdn;
+ my $port = $origin->port;
+
+ my $url = $protocol . "://" . $fqdn;
+
+ return defined($port) ? $url . ":" . $port : $url;
+}
+
sub get_example_urls {
my $self = shift;
my $id = shift;
@@ -223,7 +245,7 @@ sub read {
"dns_bypass_ip6" => $row->dns_bypass_ip6,
"dns_bypass_cname" => $row->dns_bypass_cname,
"dns_bypass_ttl" => $row->dns_bypass_ttl,
- "org_server_fqdn" => $row->org_server_fqdn,
+ "org_server_fqdn" => compute_org_server_fqdn($self, $row->id),
"multi_site_origin" => \$row->multi_site_origin,
"ccr_dns_ttl" => $row->ccr_dns_ttl,
"type" => $row->type->id,
@@ -440,13 +462,13 @@ sub check_deliveryservice_input {
$self->field('ds.routing_name')->is_equal("", $self->param('ds.routing_name') . " is not a valid hostname without periods.");
}
- my $org_host_name = $self->param('ds.org_server_fqdn');
- $self->field('ds.org_server_fqdn')->is_like( qr/^(https?:\/\/)/, "Origin Server Base URL must start with http(s)://" );
+ my $org_host_name = $self->param('origin.org_server_fqdn');
+ $self->field('origin.org_server_fqdn')->is_like( qr/^(https?:\/\/)/, "Origin Server Base URL must start with http(s)://" );
$org_host_name =~ s!^https?://?!!i;
$org_host_name =~ s/:(.*)$//;
my $port = defined($1) ? $1 : 80;
if ( !&is_hostname($org_host_name) || $port !~ /^[1-9][0-9]*$/ ) {
- $self->field('ds.org_server_fqdn')
+ $self->field('origin.org_server_fqdn')
->is_equal( "", $org_host_name . " is not a valid org server name (rfc1123) or " . $port . " is not a valid port" );
}
if ( $self->param('ds.http_bypass_fqdn') ne ""
@@ -792,6 +814,31 @@ sub delete_cfg_file {
}
}
+sub get_primary_origin_from_deliveryservice {
+ my $deliveryservice_id = shift;
+ my $deliveryservice = shift;
+ my $org_server_fqdn = shift;
+
+ if ( !defined( $org_server_fqdn ) || $org_server_fqdn eq "" ) {
+ return undef;
+ }
+
+ $org_server_fqdn =~ m{^(https?)://([^:]+)(:(\d+))?$}i;
+ my $protocol = lc($1);
+ my $fqdn = $2;
+ my $port = $4;
+
+ return {
+ name => $deliveryservice->{xml_id},
+ deliveryservice => $deliveryservice_id,
+ fqdn => $fqdn,
+ protocol => $protocol,
+ is_primary => 1,
+ port => $port,
+ tenant => $deliveryservice ->{tenant_id}
+ };
+}
+
# Update
sub update {
my $self = shift;
@@ -815,7 +862,6 @@ sub update {
geo_limit_countries => sanitize_geo_limit_countries( $self->paramAsScalar('ds.geo_limit_countries') ),
geolimit_redirect_url => $self->param('ds.geolimit_redirect_url'),
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'),
ccr_dns_ttl => $self->paramAsScalar('ds.ccr_dns_ttl'),
type => $self->typeid(),
@@ -873,6 +919,15 @@ sub update {
$update->update();
&log( $self, "Update deliveryservice with xml_id:" . $self->param('ds.xml_id'), "UICHANGE" );
+ # find this DS's primary Origin and update it too
+ my $origin_rs = $self->db->resultset('Origin')->find( { deliveryservice => $id, is_primary => 1 } );
+ if ( defined( $origin_rs ) ) {
+ my $origin = get_primary_origin_from_deliveryservice($id, \%hash, $self->paramAsScalar('origin.org_server_fqdn'));
+ if ( defined( $origin ) ) {
+ $origin_rs->update($origin);
+ }
+ }
+
# get the existing regexp set in a hash
my $regexp_set;
my $i = 0;
@@ -979,12 +1034,15 @@ sub update {
my $regexp_set = &get_regexp_set( $self, $id );
my @example_urls = &get_example_urls( $self, $id, $regexp_set, $data, $cdn_domain, $data->protocol );
my $action;
+ my $origin = {};
+ $origin->{org_server_fqdn} = compute_org_server_fqdn($self, $id);
$self->stash_profile_selector('DS_PROFILE', defined($data->profile) ? $data->profile->id : undef);
$self->stash_cdn_selector($data->cdn->id);
$self->stash(
ds => $data,
+ origin => $origin,
fbox_layout => 1,
server_count => $server_count,
static_count => $static_count,
@@ -1056,7 +1114,6 @@ sub create {
dns_bypass_ip6 => $self->paramAsScalar('ds.dns_bypass_ip6'),
dns_bypass_cname => $self->paramAsScalar('ds.dns_bypass_cname'),
dns_bypass_ttl => $self->paramAsScalar('ds.dns_bypass_ttl'),
- org_server_fqdn => $self->paramAsScalar('ds.org_server_fqdn'),
multi_site_origin => $self->paramAsScalar('ds.multi_site_origin'),
ccr_dns_ttl => $self->paramAsScalar('ds.ccr_dns_ttl'),
type => $self->paramAsScalar('ds.type'),
@@ -1098,6 +1155,14 @@ sub create {
$new_id = $insert->id;
&log( $self, "Create deliveryservice with xml_id:" . $self->param('ds.xml_id'), "UICHANGE" );
+ # create primary Origin for this DS
+ my $origin = get_primary_origin_from_deliveryservice($insert->id, $new_ds, $self->paramAsScalar('origin.org_server_fqdn'));
+ if (defined( $origin )) {
+ my $origin_rs = $self->db->resultset('Origin')->create($origin)->insert();
+ &log( $self, "Created origin [ '" . $origin_rs->name . "' ] with id: " . $origin_rs->id, "UICHANGE" );
+ }
+
+
if ( $new_id == -1 ) { # there was an error the flash will already be set,
my $referer = $self->req->headers->header('referer');
my $qstring = "?";
@@ -1183,6 +1248,7 @@ sub create {
&stash_role($self);
$self->stash(
ds => {},
+ origin => {},
fbox_layout => 1,
selected_type => $selected_type,
selected_profile => $selected_profile,
@@ -1204,6 +1270,7 @@ sub create {
&stash_role($self);
$self->stash(
ds => {},
+ origin => {},
fbox_layout => 1,
selected_type => $selected_type,
selected_profile => $selected_profile,
@@ -1327,6 +1394,7 @@ sub add {
$self->stash(
fbox_layout => 1,
ds => {},
+ origin => {},
selected_type => "",
selected_profile => "",
selected_cdn => "",
diff --git a/traffic_ops/app/lib/UI/DeliveryServiceServer.pm b/traffic_ops/app/lib/UI/DeliveryServiceServer.pm
index 1007c8e..b60c906 100644
--- a/traffic_ops/app/lib/UI/DeliveryServiceServer.pm
+++ b/traffic_ops/app/lib/UI/DeliveryServiceServer.pm
@@ -119,7 +119,7 @@ sub edit {
$self->stash( ds_id => $id );
$self->stash( assigned_servers => $dss_data );
- $self->stash( ds_name => $ds->xml_id . ' (' . $ds->org_server_fqdn . ')' );
+ $self->stash( ds_name => $ds->xml_id . ' (' . UI::DeliveryService::compute_org_server_fqdn($self, $ds->id) . ')' );
$self->stash( fbox_layout => 1 );
$self->stash( dss_data => $dss_data );
$self->stash( totals => $totals );
diff --git a/traffic_ops/app/lib/UI/Job.pm b/traffic_ops/app/lib/UI/Job.pm
index 2be1810..e875107 100644
--- a/traffic_ops/app/lib/UI/Job.pm
+++ b/traffic_ops/app/lib/UI/Job.pm
@@ -74,7 +74,7 @@ sub newjob {
$org_server_fqdn =~ s/\/$//;
}
else {
- $org_server_fqdn = $ds->org_server_fqdn;
+ $org_server_fqdn = UI::DeliveryService::compute_org_server_fqdn($self, $ds->id);
}
my $ds_id = $ds->id;
diff --git a/traffic_ops/app/t/deliveryservice.t b/traffic_ops/app/t/deliveryservice.t
index ce3fdfc..eca63e3 100644
--- a/traffic_ops/app/t/deliveryservice.t
+++ b/traffic_ops/app/t/deliveryservice.t
@@ -77,7 +77,7 @@ ok $t->post_ok(
'ds.max_dns_answers' => '0',
'ds.miss_lat' => '41.881944',
'ds.miss_long' => '-87.627778',
- 'ds.org_server_fqdn' => 'http://jvd.knutsel.com',
+ 'origin.org_server_fqdn' => 'http://jvd.knutsel.com',
'ds.multi_site_origin' => '0',
'ds.multi_site_origin_algorithm' => '0',
'ds.profile' => '100',
@@ -130,7 +130,7 @@ ok $t->post_ok(
'ds.max_dns_answers' => '0',
'ds.miss_lat' => '41.881944',
'ds.miss_long' => '-87.627778',
- 'ds.org_server_fqdn' => 'http://jvd-1.knutsel.com',
+ 'origin.org_server_fqdn' => 'http://jvd-1.knutsel.com',
'ds.multi_site_origin' => '0',
'ds.multi_site_origin_algorithm' => '0',
'ds.profile' => '100',
@@ -183,7 +183,7 @@ ok $t->post_ok(
'ds.max_dns_answers' => '0',
'ds.miss_lat' => '41.881944',
'ds.miss_long' => '-87.627778',
- 'ds.org_server_fqdn' => 'http://jvd.knutsel.com',
+ 'origin.org_server_fqdn' => 'http://jvd.knutsel.com',
'ds.multi_site_origin' => '0',
'ds.multi_site_origin_algorithm' => '0',
'ds.profile' => '100',
@@ -252,7 +252,7 @@ ok $t->post_ok(
'ds.max_dns_answers' => '1',
'ds.miss_lat' => '0',
'ds.miss_long' => '0',
- 'ds.org_server_fqdn' => 'http://update.knutsel.com',
+ 'origin.org_server_fqdn' => 'http://update.knutsel.com',
'ds.multi_site_origin' => '0',
'ds.multi_site_origin_algorithm' => '0',
'ds.profile' => '200',
diff --git a/traffic_ops/app/t/purge.t b/traffic_ops/app/t/purge.t
index 97286e6..dd3bdbe 100644
--- a/traffic_ops/app/t/purge.t
+++ b/traffic_ops/app/t/purge.t
@@ -48,7 +48,10 @@ $t->post_ok( '/login', => form => { u => 'admin', p => 'password' } )->status_is
my $q = "SELECT deliveryservice.id,
deliveryservice.xml_id,
- deliveryservice.org_server_fqdn,
+ (SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', o.port::text), ':')
+ FROM origin o
+ WHERE o.deliveryservice = deliveryservice.id
+ AND o.is_primary) as org_server_fqdn,
deliveryservice.type,
profile.id AS profile_id,
cdn.name AS cdn_name
diff --git a/traffic_ops/app/templates/delivery_service/_form.html.ep b/traffic_ops/app/templates/delivery_service/_form.html.ep
index 35b72a5..ed500d4 100644
--- a/traffic_ops/app/templates/delivery_service/_form.html.ep
+++ b/traffic_ops/app/templates/delivery_service/_form.html.ep
@@ -341,14 +341,14 @@
<% } %>
</div>
<div class="block form-row" id="org_server_fqdn_row">
- <% unless (field('ds.org_server_fqdn')->valid) { %>
- <span class="field-with-error"><%= field('ds.org_server_fqdn')->error %></span>
+ <% unless (field('origin.org_server_fqdn')->valid) { %>
+ <span class="field-with-error"><%= field('origin.org_server_fqdn')->error %></span>
<% } %>
- %= label_for 'org_server_fqdn' => '* Origin Server Base URL', class => 'label'
+ %= label_for 'origin.org_server_fqdn' => '* Origin Server Base URL', class => 'label'
<% if ($priv_level >= 20) { %>
- %= field('ds.org_server_fqdn')->text(class => 'field', id => 'org_server_fqdn', name => 'ds.org_server_fqdn');
+ %= field('origin.org_server_fqdn')->text(class => 'field', id => 'org_server_fqdn', name => 'origin.org_server_fqdn');
<% } else { %>
- %= field('ds.org_server_fqdn')->text(class => 'field', readonly => 'readonly');
+ %= field('origin.org_server_fqdn')->text(class => 'field', readonly => 'readonly');
<% } %>
</div>
<div class="block form-row" id="multi_site_origin_row">
diff --git a/traffic_ops/testing/api/v13/tc-fixtures.json b/traffic_ops/testing/api/v13/tc-fixtures.json
index 2653051..6ce32b1 100644
--- a/traffic_ops/testing/api/v13/tc-fixtures.json
+++ b/traffic_ops/testing/api/v13/tc-fixtures.json
@@ -329,7 +329,6 @@
"fqdn": "origin1.example.com",
"ipAddress": "1.2.3.4",
"ip6Address": "dead:beef:cafe::42",
- "isPrimary": false,
"port": 1234,
"protocol": "http"
},
@@ -338,7 +337,6 @@
"fqdn": "origin2.example.com",
"ipAddress": "5.6.7.8",
"ip6Address": "cafe::42",
- "isPrimary": false,
"port": 5678,
"protocol": "https"
}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index 1b95ce1..cdfc319 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -260,7 +260,8 @@ func validateTypeFields(db *sqlx.DB, ds *tc.DeliveryServiceNullableV12) []error
"multiSiteOrigin": validation.Validate(ds.MultiSiteOrigin,
validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName))),
"orgServerFqdn": validation.Validate(ds.OrgServerFQDN,
- validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName))),
+ validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName)),
+ validation.NewStringRule(validateOrgServerFQDN, "must start with http:// or https:// and be followed by a valid hostname with an optional port (no trailing slash)")),
"protocol": validation.Validate(ds.Protocol,
validation.By(requiredIfMatchesTypeName([]string{SteeringRegexType, DNSRegexType, HTTPRegexType}, typeName))),
"qstringIgnore": validation.Validate(ds.QStringIgnore,
@@ -275,6 +276,14 @@ func validateTypeFields(db *sqlx.DB, ds *tc.DeliveryServiceNullableV12) []error
return nil
}
+func validateOrgServerFQDN(orgServerFQDN string) bool {
+ _, fqdn, port, err := parseOrgServerFQDN(orgServerFQDN)
+ if err != nil || !govalidator.IsHost(*fqdn) || (port != nil && !govalidator.IsPort(*port)) {
+ return false
+ }
+ return true
+}
+
func requiredIfMatchesTypeName(patterns []string, typeName string) func(interface{}) error {
return func(value interface{}) error {
switch v := value.(type) {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index b5d61ee..77045f0 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -25,6 +25,7 @@ import (
"errors"
"fmt"
"net/http"
+ "regexp"
"strconv"
"strings"
@@ -196,7 +197,7 @@ func create(db *sql.DB, cfg config.Config, user *auth.CurrentUser, ds tc.Deliver
commitTx := false
defer dbhelpers.FinishTx(tx, &commitTx)
- resultRows, err := tx.Query(insertQuery(), &ds.Active, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CheckPath, &deepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnabled, &ds.LogsEnabled, &ds.LongD [...]
+ resultRows, err := tx.Query(insertQuery(), &ds.Active, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CheckPath, &deepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnabled, &ds.LogsEnabled, &ds.LongD [...]
if err != nil {
if pqerr, ok := err.(*pq.Error); ok {
@@ -270,6 +271,11 @@ func create(db *sql.DB, cfg config.Config, user *auth.CurrentUser, ds tc.Deliver
if err := createDNSSecKeys(tx, cfg, *ds.ID, *ds.XMLID, cdnName, cdnDomain, dnssecEnabled, ds.ExampleURLs); err != nil {
return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating DNSSEC keys: " + err.Error())
}
+
+ if err := createPrimaryOrigin(db, tx, user, ds); err != nil {
+ return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating delivery service: " + err.Error())
+ }
+
ds.LastUpdated = &lastUpdated
commitTx = true
api.CreateChangeLogRaw(api.ApiChange, "Created ds: "+*ds.XMLID+" id: "+strconv.Itoa(*ds.ID), *user, db)
@@ -306,6 +312,88 @@ func createDefaultRegex(tx *sql.Tx, dsID int, xmlID string) error {
return nil
}
+func parseOrgServerFQDN(orgServerFQDN string) (*string, *string, *string, error) {
+ originRegex := regexp.MustCompile(`^(https?)://([^:]+)(:(\d+))?$`)
+ matches := originRegex.FindStringSubmatch(orgServerFQDN)
+ if len(matches) == 0 {
+ return nil, nil, nil, fmt.Errorf("unable to parse invalid orgServerFqdn: '%s'", orgServerFQDN)
+ }
+
+ protocol := strings.ToLower(matches[1])
+ FQDN := matches[2]
+
+ if len(protocol) == 0 || len(FQDN) == 0 {
+ return nil, nil, nil, fmt.Errorf("empty Origin protocol or FQDN parsed from '%s'", orgServerFQDN)
+ }
+
+ var port *string
+ if len(matches[4]) != 0 {
+ port = &matches[4]
+ }
+ return &protocol, &FQDN, port, nil
+}
+
+func createPrimaryOrigin(db *sql.DB, tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullableV13) error {
+ if ds.OrgServerFQDN == nil {
+ return nil
+ }
+
+ protocol, fqdn, port, err := parseOrgServerFQDN(*ds.OrgServerFQDN)
+ if err != nil {
+ return fmt.Errorf("creating primary origin: %v", err)
+ }
+
+ originID := 0
+ q := `INSERT INTO origin (name, fqdn, protocol, is_primary, port, deliveryservice, tenant) VALUES ($1, $2, $3, TRUE, $4, $5, $6) RETURNING id`
+ if err := tx.QueryRow(q, ds.XMLID, fqdn, protocol, port, ds.ID, ds.TenantID).Scan(&originID); err != nil {
+ return fmt.Errorf("insert origin from '%s': %s", *ds.OrgServerFQDN, err.Error())
+ }
+
+ api.CreateChangeLogRaw(api.ApiChange, "Created primary origin id: "+strconv.Itoa(originID)+" for delivery service: "+*ds.XMLID, *user, db)
+
+ return nil
+}
+
+func updatePrimaryOrigin(db *sql.DB, tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullableV13) error {
+ count := 0
+ q := `SELECT count(*) FROM origin WHERE deliveryservice = $1 AND is_primary`
+ if err := tx.QueryRow(q, *ds.ID).Scan(&count); err != nil {
+ return fmt.Errorf("querying existing primary origin for ds %s: %s", *ds.XMLID, err.Error())
+ }
+
+ if ds.OrgServerFQDN == nil || *ds.OrgServerFQDN == "" {
+ if count == 1 {
+ // the update is removing the existing orgServerFQDN, so the existing row needs to be deleted
+ q = `DELETE FROM origin WHERE deliveryservice = $1 AND is_primary`
+ if _, err := tx.Exec(q, *ds.ID); err != nil {
+ return fmt.Errorf("deleting primary origin for ds %s: %s", *ds.XMLID, err.Error())
+ }
+ api.CreateChangeLogRaw(api.ApiChange, "Deleted primary origin for delivery service: "+*ds.XMLID, *user, db)
+ }
+ return nil
+ }
+
+ if count == 0 {
+ // orgServerFQDN is going from null to not null, so the primary origin needs to be created
+ return createPrimaryOrigin(db, tx, user, ds)
+ }
+
+ protocol, fqdn, port, err := parseOrgServerFQDN(*ds.OrgServerFQDN)
+ if err != nil {
+ return fmt.Errorf("updating primary origin: %v", err)
+ }
+
+ name := ""
+ q = `UPDATE origin SET protocol = $1, fqdn = $2, port = $3 WHERE is_primary AND deliveryservice = $4 RETURNING name`
+ if err := tx.QueryRow(q, protocol, fqdn, port, *ds.ID).Scan(&name); err != nil {
+ return fmt.Errorf("update primary origin for ds %s from '%s': %s", *ds.XMLID, *ds.OrgServerFQDN, err.Error())
+ }
+
+ api.CreateChangeLogRaw(api.ApiChange, "Updated primary origin: "+name+" for delivery service: "+*ds.XMLID, *user, db)
+
+ return nil
+}
+
func getOldHostName(id int, tx *sql.Tx) (string, error) {
q := `
SELECT ds.xml_id, ds.protocol, type.name, ds.routing_name, cdn.domain_name
@@ -423,7 +511,7 @@ func update(db *sql.DB, cfg config.Config, user auth.CurrentUser, ds *tc.Deliver
deepCachingType = ds.DeepCachingType.String() // necessary, because DeepCachingType's default needs to insert the string, not "", and Query doesn't call .String().
}
- resultRows, err := tx.Query(updateDSQuery(), &ds.Active, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CheckPath, &deepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnabled, &ds.LogsEnabled, &ds.Lon [...]
+ resultRows, err := tx.Query(updateDSQuery(), &ds.Active, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CheckPath, &deepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnabled, &ds.LogsEnabled, &ds.Lon [...]
if err != nil {
if err, ok := err.(*pq.Error); ok {
@@ -506,6 +594,11 @@ func update(db *sql.DB, cfg config.Config, user auth.CurrentUser, ds *tc.Deliver
if err := ensureCacheURLParams(tx, *ds.ID, *ds.XMLID, ds.CacheURL); err != nil {
return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating mid cacheurl parameters: " + err.Error())
}
+
+ if err := updatePrimaryOrigin(db, tx, &user, *ds); err != nil {
+ return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("updating delivery service: " + err.Error())
+ }
+
ds.LastUpdated = &lastUpdated
commitTx = true
api.CreateChangeLogRaw(api.ApiChange, "Updated ds: "+*ds.XMLID+" id: "+strconv.Itoa(*ds.ID), user, db)
@@ -1018,7 +1111,10 @@ ds.mid_header_rewrite,
COALESCE(ds.miss_lat, 0.0),
COALESCE(ds.miss_long, 0.0),
ds.multi_site_origin,
-ds.org_server_fqdn,
+(SELECT o.protocol::::text || ':://' || o.fqdn || rtrim(concat('::', o.port::::text), '::')
+ FROM origin o
+ WHERE o.deliveryservice = ds.id
+ AND o.is_primary) as org_server_fqdn,
ds.origin_shield,
ds.profile as profileID,
profile.name as profile_name,
@@ -1085,24 +1181,23 @@ mid_header_rewrite=$30,
miss_lat=$31,
miss_long=$32,
multi_site_origin=$33,
-org_server_fqdn=$34,
-origin_shield=$35,
-profile=$36,
-protocol=$37,
-qstring_ignore=$38,
-range_request_handling=$39,
-regex_remap=$40,
-regional_geo_blocking=$41,
-remap_text=$42,
-routing_name=$43,
-signing_algorithm=$44,
-ssl_key_version=$45,
-tenant_id=$46,
-tr_request_headers=$47,
-tr_response_headers=$48,
-type=$49,
-xml_id=$50
-WHERE id=$51
+origin_shield=$34,
+profile=$35,
+protocol=$36,
+qstring_ignore=$37,
+range_request_handling=$38,
+regex_remap=$39,
+regional_geo_blocking=$40,
+remap_text=$41,
+routing_name=$42,
+signing_algorithm=$43,
+ssl_key_version=$44,
+tenant_id=$45,
+tr_request_headers=$46,
+tr_response_headers=$47,
+type=$48,
+xml_id=$49
+WHERE id=$50
RETURNING last_updated
`
}
@@ -1143,7 +1238,6 @@ mid_header_rewrite,
miss_lat,
miss_long,
multi_site_origin,
-org_server_fqdn,
origin_shield,
profile,
protocol,
@@ -1161,7 +1255,7 @@ tr_response_headers,
type,
xml_id
)
-VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$50)
+VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49)
RETURNING id, last_updated
`
}
diff --git a/traffic_ops/traffic_ops_golang/origin/origins.go b/traffic_ops/traffic_ops_golang/origin/origins.go
index f514043..8db7541 100644
--- a/traffic_ops/traffic_ops_golang/origin/origins.go
+++ b/traffic_ops/traffic_ops_golang/origin/origins.go
@@ -98,7 +98,6 @@ func (origin *TOOrigin) Validate(db *sqlx.DB) []error {
"fqdn": validation.Validate(origin.FQDN, validation.Required, is.DNSName),
"ip6Address": validation.Validate(origin.IP6Address, validation.NilOrNotEmpty, is.IPv6),
"ipAddress": validation.Validate(origin.IPAddress, validation.NilOrNotEmpty, is.IPv4),
- "isPrimary": validation.Validate(origin.Name, validation.NotNil),
"name": validation.Validate(origin.Name, validation.Required, noSpaces),
"port": validation.Validate(origin.Port, validation.NilOrNotEmpty.Error(portErr), validation.Min(1).Error(portErr), validation.Max(65535).Error(portErr)),
"profileId": validation.Validate(origin.ProfileID, validation.Min(1)),
@@ -202,6 +201,7 @@ func getOrigins(params map[string]string, db *sqlx.DB, privLevel int) ([]v13.Ori
"deliveryservice": dbhelpers.WhereColumnInfo{"o.deliveryservice", api.IsInt},
"id": dbhelpers.WhereColumnInfo{"o.id", api.IsInt},
"name": dbhelpers.WhereColumnInfo{"o.name", nil},
+ "primary": dbhelpers.WhereColumnInfo{"o.is_primary", api.IsBool},
"profileId": dbhelpers.WhereColumnInfo{"o.profile", api.IsInt},
"tenant": dbhelpers.WhereColumnInfo{"o.tenant", api.IsInt},
}
@@ -331,6 +331,17 @@ func (origin *TOOrigin) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return tc.DBError, tc.SystemError
}
+ isPrimary := false
+ ds := 0
+ q := `SELECT is_primary, deliveryservice FROM origin WHERE id = $1`
+ if err := tx.QueryRow(q, *origin.ID).Scan(&isPrimary, &ds); err != nil {
+ log.Errorf("updating origin %d, received error in select: %v", *origin.ID, err)
+ return tc.DBError, tc.SystemError
+ }
+ if isPrimary && *origin.DeliveryServiceID != ds {
+ return errors.New("cannot update the delivery service of a primary origin"), tc.DataConflictError
+ }
+
log.Debugf("about to run exec query: %s with origin: %++v", updateQuery(), origin)
resultRows, err := tx.NamedQuery(updateQuery(), origin)
if err != nil {
@@ -385,7 +396,6 @@ deliveryservice=:deliveryservice_id,
fqdn=:fqdn,
ip6_address=:ip6_address,
ip_address=:ip_address,
-is_primary=:is_primary,
name=:name,
port=:port,
profile=:profile_id,
@@ -479,7 +489,6 @@ deliveryservice,
fqdn,
ip6_address,
ip_address,
-is_primary,
name,
port,
profile,
@@ -491,7 +500,6 @@ tenant) VALUES (
:fqdn,
:ip6_address,
:ip_address,
-:is_primary,
:name,
:port,
:profile_id,
@@ -519,6 +527,17 @@ func (origin *TOOrigin) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
log.Error.Printf("could not begin transaction: %v", err)
return tc.DBError, tc.SystemError
}
+
+ isPrimary := false
+ q := `SELECT is_primary FROM origin WHERE id = $1`
+ if err := tx.QueryRow(q, *origin.ID).Scan(&isPrimary); err != nil {
+ log.Errorf("deleting origin %d, received error selecting is_primary: %v", *origin.ID, err)
+ return tc.DBError, tc.SystemError
+ }
+ if isPrimary {
+ return errors.New("cannot delete a primary origin"), tc.DataConflictError
+ }
+
log.Debugf("about to run exec query: %s with origin: %++v", deleteQuery(), origin)
result, err := tx.NamedExec(deleteQuery(), origin)
if err != nil {
diff --git a/traffic_ops/traffic_ops_golang/origin/origins_test.go b/traffic_ops/traffic_ops_golang/origin/origins_test.go
index c7d522a..a44c1e6 100644
--- a/traffic_ops/traffic_ops_golang/origin/origins_test.go
+++ b/traffic_ops/traffic_ops_golang/origin/origins_test.go
@@ -179,7 +179,6 @@ func TestValidate(t *testing.T) {
Name: nil,
DeliveryServiceID: nil,
FQDN: nil,
- IsPrimary: nil,
Protocol: nil,
}
errs := test.SortErrors(c.Validate(nil))
@@ -187,7 +186,6 @@ func TestValidate(t *testing.T) {
expectedErrs := []error{
errors.New(`'deliveryServiceId' is required`),
errors.New(`'fqdn' cannot be blank`),
- errors.New(`'isPrimary' is required`),
errors.New(`'name' cannot be blank`),
errors.New(`'protocol' cannot be blank`),
}
@@ -202,7 +200,6 @@ func TestValidate(t *testing.T) {
fqdn := "is.a.valid.hostname"
ip6 := "dead:beef::42"
ip := "1.2.3.4"
- primary := false
port := 65535
pro := "http"
lu := tc.TimeNoMod{Time: time.Now()}
@@ -212,7 +209,6 @@ func TestValidate(t *testing.T) {
FQDN: &fqdn,
IP6Address: &ip6,
IPAddress: &ip,
- IsPrimary: &primary,
Port: &port,
Protocol: &pro,
LastUpdated: &lu,
--
To stop receiving notification emails like this one, please contact
elsloo@apache.org.