Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TC-376] Add multiple steering targets and ordering #647

Closed
wants to merge 16 commits into from
20 changes: 18 additions & 2 deletions docs/source/admin/quick_howto/steering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Configure Delivery Service Steering
:scale: 100%
:align: center

5) As the steering user, assign weights to target delivery services. This will require logging in to Traffic Ops first via ``http://to.kabletown.net/api/1.2/user/login`` and storing the mojolicious cookie.
5) As the steering user, assign weights or orders to target delivery services. Assignments must either have a value for weight or order, but not both. The value of weight must be a positive integer, while the value of order can be any integer. This will require logging in to Traffic Ops first via ``http://to.kabletown.net/api/1.2/user/login`` and storing the mojolicious cookie.

Sample cURL: ``curl -H "Cookie: mojolicious=xxxyyy" -XPUT "https://to.kabletown.net/internal/api/1.2/steering/steering-ds" -d @/tmp/steering.json``

Expand All @@ -61,6 +61,14 @@ Configure Delivery Service Steering
"weight": "9000",
"deliveryService": "target-deliveryservice-2"
}
{
"order": -1,
"deliveryService": "target-deliveryservice-3"
}
{
"order": 3,
"deliveryService": "target-deliveryservice-4"
}
]
}

Expand Down Expand Up @@ -88,8 +96,16 @@ Configure Delivery Service Steering
"weight": "9000",
"deliveryService": "target-deliveryservice-2"
}
{
"order": -1,
"deliveryService": "target-deliveryservice-3"
}
{
"order": 3,
"deliveryService": "target-deliveryservice-4"
}
]
}

7) Any requests to Traffic Router for the steering delivery service should now be routed to target delivery services based on configured weight. Example: ``curl -Lvs http://tr.steering-ds.cdn.kabletown.net/foo``
7) Any requests to Traffic Router for the steering delivery service should now be routed to target delivery services based on configured weight or order. Example: ``curl -Lvs http://tr.steering-ds.cdn.kabletown.net/foo``

16 changes: 16 additions & 0 deletions traffic_ops/app/db/migrations/20170601183753_steering_target.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
ALTER TABLE steering_target RENAME COLUMN weight TO value;
ALTER TABLE steering_target ADD COLUMN IF NOT EXISTS type bigint;
ALTER TABLE steering_target ADD CONSTRAINT steering_target_type_fkey
FOREIGN KEY ("type")
REFERENCES "type" (id);


-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
ALTER TABLE steering_target DROP CONSTRAINT steering_target_type_fkey;
ALTER TABLE steering_target DROP COLUMN IF EXISTS type;
ALTER TABLE steering_target RENAME COLUMN value to weight;

2 changes: 2 additions & 0 deletions traffic_ops/app/db/patches.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@


-- THIS FILE INCLUDES POST-MIGRATION DATA FIXES REQUIRED OF TRAFFIC OPS
UPDATE steering_target SET "type" = (SELECT id FROM type WHERE name = 'STEERING_WEIGHT') where "type" is NULL;;
ALTER TABLE steering_target ALTER COLUMN type SET NOT NULL;
4 changes: 4 additions & 0 deletions traffic_ops/app/db/seeds.sql
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ insert into type (name, description, use_in_table) values ('A_RECORD', 'Static D
insert into type (name, description, use_in_table) values ('AAAA_RECORD', 'Static DNS AAAA entry', 'staticdnsentry') ON CONFLICT (name) DO NOTHING;
insert into type (name, description, use_in_table) values ('CNAME_RECORD', 'Static DNS CNAME entry', 'staticdnsentry') ON CONFLICT (name) DO NOTHING;

--steering_target types
insert into type (name, description, use_in_table) values ('STEERING_WEIGHT', 'Weighted steering target', 'steering_target') ON CONFLICT (name) DO NOTHING;
insert into type (name, description, use_in_table) values ('STEERING_ORDER', 'Ordered steering target', 'steering_target') ON CONFLICT (name) DO NOTHING;

-- users
insert into tm_user (username, role, full_name, token) values ('extension', 3, 'Extension User, DO NOT DELETE', '91504CE6-8E4A-46B2-9F9F-FE7C15228498') ON CONFLICT DO NOTHING;

Expand Down
45 changes: 39 additions & 6 deletions traffic_ops/app/lib/API/DeliveryService/Steering.pm
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,22 @@ sub find_steering {

my $targets = $steering_entry->{"targets"};

push(@{$targets},{
my $type = $self->get_type($row->type);

if ( $row->type eq "STEERING_ORDER" ) {
push(@{$targets},{
'deliveryService' => $row->target_xml_id,
'order' => $row->value,
'weight' => 0
});
}
else {
push(@{$targets},{
'deliveryService' => $row->target_xml_id,
'weight' => $row->weight,
});
'order' => 0,
'weight' => $row->value
});
}

}

Expand Down Expand Up @@ -179,6 +191,20 @@ sub get_ds_id {
return $self->db->resultset('Deliveryservice')->search( { xml_id => $xml_id } )->get_column('id')->single();
}

sub get_type {
my $self = shift;
my $id = shift;
my $type;

if ( $id =~ /^\d+$/ ) {
$type = $self->db->resultset('Type')->search( { id => $id } )->get_column('name')->single();
}
else {
$type = $self->db->resultset('Type')->search( { name => $id } )->get_column('id')->single();
}
return $type;
}

sub update() {
my $self = shift;

Expand All @@ -205,7 +231,7 @@ sub update() {
my $dsu_row = $self->db->resultset('DeliveryserviceTmuser')->search(
{tm_user_id => $user_id, deliveryservice => $row->steering_id})->single;

if (!$dsu_row) {
if (!$dsu_row && !&is_admin($self) ) {
return $self->render(json => {"message" => "unauthorized"}, status => 401);
}

Expand All @@ -222,7 +248,7 @@ sub update() {
my $req_targets = $self->req->json->{'targets'};

foreach my $req_target (@{$req_targets}) {
if (!$req_target->{'deliveryService'} || !$req_target->{'weight'}) {
if (!$req_target->{'deliveryService'} && ( !$req_target->{'weight'} || !$req_target->{'order'} ) || ( $req_target->{'weight'} && $req_target->{'order'} ) ) {
return $self->render(json => {"message" => "please provide a valid json for targets"}, status => 400);
}
if (!exists($valid_targets->{$req_target->{'deliveryService'}})) {
Expand Down Expand Up @@ -251,7 +277,14 @@ sub update() {

if ($req_target->{'weight'}) {
my $steering_target_row = $self->db->resultset('SteeringTarget')->find({ deliveryservice => $steering_id, target => $target_id});
$steering_target_row->weight($req_target->{weight});
$steering_target_row->value($req_target->{weight});
$steering_target_row->type($self->get_type("STEERING_WEIGHT"));
$steering_target_row->update;
}
elsif ($req_target->{'order'}) {
my $steering_target_row = $self->db->resultset('SteeringTarget')->find({ deliveryservice => $steering_id, target => $target_id});
$steering_target_row->value($req_target->{order});
$steering_target_row->type($self->get_type("STEERING_ORDER"));
$steering_target_row->update;
}

Expand Down
31 changes: 27 additions & 4 deletions traffic_ops/app/lib/Schema/Result/SteeringTarget.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ __PACKAGE__->table("steering_target");
data_type: 'bigint'
is_nullable: 0

=head2 weight
=head2 value

data_type: 'bigint'
is_nullable: 0
Expand All @@ -46,14 +46,20 @@ __PACKAGE__->table("steering_target");
is_nullable: 1
original: {default_value => \"now()"}

=head2 type

data_type: 'bigint'
is_foreign_key: 1
is_nullable: 0

=cut

__PACKAGE__->add_columns(
"deliveryservice",
{ data_type => "bigint", is_foreign_key => 1, is_nullable => 0 },
"target",
{ data_type => "bigint", is_nullable => 0 },
"weight",
"value",
{ data_type => "bigint", is_nullable => 0 },
"last_updated",
{
Expand All @@ -62,6 +68,8 @@ __PACKAGE__->add_columns(
is_nullable => 1,
original => { default_value => \"now()" },
},
"type",
{ data_type => "bigint", is_foreign_key => 1, is_nullable => 0 },
);

=head1 PRIMARY KEY
Expand Down Expand Up @@ -110,9 +118,24 @@ __PACKAGE__->belongs_to(
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },
);

=head2 type

Type: belongs_to

Related object: L<Schema::Result::Type>

=cut

__PACKAGE__->belongs_to(
"type",
"Schema::Result::Type",
{ id => "type" },
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" },
);


# Created by DBIx::Class::Schema::Loader v0.07045 @ 2016-11-15 09:35:47
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gZIXjQohI79d92yjQT6sxg
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-05-31 20:31:43
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:DYSNby1kQgL/sEtaCwOgbw


# You can replace this text with custom code or comments, and it will be preserved on regeneration
Expand Down
9 changes: 6 additions & 3 deletions traffic_ops/app/lib/Schema/Result/SteeringView.pm
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ __PACKAGE__->table("SteeringView");
__PACKAGE__->result_source_instance->is_virtual(1);

__PACKAGE__->result_source_instance->view_definition(
"select s.xml_id as steering_xml_id, s.id as steering_id, t.xml_id as target_xml_id, t.id as target_id, weight from steering_target
"select s.xml_id as steering_xml_id, s.id as steering_id, t.xml_id as target_xml_id, t.id as target_id, value, tp.name as type from steering_target
join deliveryservice s on s.id = steering_target.deliveryservice
join deliveryservice t on t.id = steering_target.target"
join deliveryservice t on t.id = steering_target.target
join type tp on tp.id = steering_target.type"
);

__PACKAGE__->add_columns(
Expand All @@ -44,8 +45,10 @@ __PACKAGE__->add_columns(
{ data_type => "varchar", is_nullable => 0, size => 50 },
"target_id",
{ data_type => "integer", is_nullable => 0, size => 11 },
"weight",
"value",
{ data_type => "integer", extra => { unsigned => 1 }, is_nullable => 0 },
"type",
{ data_type => "integer", is_nullable => 0 }
);

1;