Skip to content

Commit 337c512

Browse files
committed
wip: support for route options in cf push/manifest operations
(Route update note yet functional)
1 parent e9e33d3 commit 337c512

File tree

5 files changed

+147
-3
lines changed

5 files changed

+147
-3
lines changed

app/actions/manifest_route_update.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ def find_or_create_valid_route(app, manifest_route, user_audit_info)
9292
domain: existing_domain,
9393
manifest_triggered: true
9494
)
95+
elsif route[:options] != manifest_route[:options]
96+
message = RouteUpdateMessage.new({
97+
'host' => host,
98+
'path' => manifest_route[:path],
99+
'port' => manifest_route[:port],
100+
'options' => manifest_route[:options]
101+
})
102+
route = RouteUpdate.update(route, message)
95103
elsif route.space.guid != app.space_guid
96104
raise InvalidRoute.new('Routes cannot be mapped to destinations in different spaces')
97105
end

app/messages/manifest_routes_update_message.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ def manifest_route_mappings
6161
@manifest_route_mappings ||= routes.map do |route|
6262
{
6363
route: ManifestRoute.parse(route[:route], route[:options]),
64-
protocol: route[:protocol]
64+
protocol: route[:protocol],
65+
options: route[:options]
6566
}
6667
end
6768
end

app/presenters/v3/app_manifest_presenters/route_properties_presenter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def to_hash(route_mappings:, app:, **_)
1010
protocol: route_mapping.protocol
1111
}
1212

13-
route_hash[:options] = route_mapping.route.options if route_mapping.route.options && route_mapping.route.options['lb_algo']
13+
route_hash[:options]['loadbalancing-algorithm'] = route_mapping.route.options['lb_algo'] if route_mapping.route.options && route_mapping.route.options['lb_algo']
1414

1515
route_hash
1616
end

lib/cloud_controller/app_manifest/manifest_route.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def to_hash
4949
{
5050
candidate_host_domain_pairs: pairs,
5151
port: @attrs[:port],
52-
path: @attrs[:path]
52+
path: @attrs[:path],
53+
options: @attrs[:options]
5354
}
5455
end
5556

spec/request/space_manifests_spec.rb

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,140 @@
624624
end
625625
end
626626

627+
describe 'route options' do
628+
context 'when an empty route options hash is provided' do
629+
let(:yml_manifest) do
630+
{
631+
'applications' => [
632+
{
633+
'name' => app1_model.name,
634+
'routes' => [
635+
{ 'route' => "https://#{route.host}.#{route.domain.name}",
636+
'options' => {} }
637+
]
638+
}
639+
]
640+
}.to_yaml
641+
end
642+
643+
it 'applies the manifest' do
644+
post "/v3/spaces/#{space.guid}/actions/apply_manifest", yml_manifest, yml_headers(user_header)
645+
646+
expect(last_response.status).to eq(202)
647+
end
648+
end
649+
650+
context 'when an invalid route option is provided' do
651+
let(:yml_manifest) do
652+
{
653+
'applications' => [
654+
{
655+
'name' => app1_model.name,
656+
'routes' => [
657+
{ 'route' => "https://#{route.host}.#{route.domain.name}",
658+
'options' => {
659+
'doesnt-exist' => 'doesnt-exist'
660+
} }
661+
]
662+
}
663+
]
664+
}.to_yaml
665+
end
666+
667+
it 'returns a 422' do
668+
post "/v3/spaces/#{space.guid}/actions/apply_manifest", yml_manifest, yml_headers(user_header)
669+
670+
expect(last_response).to have_status_code(422)
671+
expect(last_response).to have_error_message('Routes contains an invalid loadbalancing-algorithm option')
672+
end
673+
end
674+
675+
context 'loadbalancing-algorithm' do
676+
context 'when the loadbalancing-algorithm is not supported' do
677+
let(:yml_manifest) do
678+
{
679+
'applications' => [
680+
{
681+
'name' => app1_model.name,
682+
'routes' => [
683+
{ 'route' => "https://#{route.host}.#{route.domain.name}",
684+
'options' => {
685+
'loadbalancing-algorithm' => 'unsupported-lb-algorithm'
686+
} }
687+
]
688+
}
689+
]
690+
}.to_yaml
691+
end
692+
693+
it 'returns a 422' do
694+
post "/v3/spaces/#{space.guid}/actions/apply_manifest", yml_manifest, yml_headers(user_header)
695+
696+
expect(last_response).to have_status_code(422)
697+
expect(last_response).to have_error_message('Routes contains an invalid loadbalancing-algorithm option')
698+
end
699+
end
700+
701+
context 'when the loadbalancing-algorithm is supported' do
702+
context 'when a new route is added' do
703+
let(:yml_manifest) do
704+
{
705+
'applications' => [
706+
{ 'name' => app1_model.name,
707+
'routes' => [
708+
{ 'route' => "https://round-robin-app.#{shared_domain.name}",
709+
'options' => {
710+
'loadbalancing-algorithm' => 'round-robin'
711+
} }
712+
] }
713+
]
714+
}.to_yaml
715+
end
716+
717+
it 'adds and removes the loadbalancing-algorithm to the route' do
718+
post "/v3/spaces/#{space.guid}/actions/apply_manifest", yml_manifest, yml_headers(user_header)
719+
720+
expect(last_response.status).to eq(202)
721+
job_guid = VCAP::CloudController::PollableJobModel.last.guid
722+
723+
Delayed::Worker.new.work_off
724+
expect(VCAP::CloudController::PollableJobModel.find(guid: job_guid)).to be_complete, VCAP::CloudController::PollableJobModel.find(guid: job_guid).cf_api_error
725+
726+
app1_model.reload
727+
expect(app1_model.routes.first.options).to eq({ 'lb_algo' => 'round-robin' })
728+
# expect(route.route_mappings_dataset.first(app: app1_model).protocol).to eq('http1')
729+
# expect(second_route.route_mappings_dataset.first(app: app1_model).protocol).to eq('http2')
730+
731+
### remove the loadbalancing-algorithm from the route
732+
733+
yml_manifest = {
734+
'applications' => [
735+
{ 'name' => app1_model.name,
736+
'routes' => [
737+
{ 'route' => "https://round-robin-app.#{shared_domain.name}" }
738+
] }
739+
]
740+
}.to_yaml
741+
742+
post "/v3/spaces/#{space.guid}/actions/apply_manifest", yml_manifest, yml_headers(user_header)
743+
744+
expect(last_response.status).to eq(202)
745+
job_guid = VCAP::CloudController::PollableJobModel.last.guid
746+
747+
Delayed::Worker.new.work_off
748+
expect(VCAP::CloudController::PollableJobModel.find(guid: job_guid)).to be_complete, VCAP::CloudController::PollableJobModel.find(guid: job_guid).cf_api_error
749+
750+
app1_model.reload
751+
expect(app1_model.routes.first.options).to eq({})
752+
753+
end
754+
755+
end
756+
end
757+
end
758+
759+
end
760+
627761
describe 'audit events' do
628762
let!(:process1) { nil }
629763

0 commit comments

Comments
 (0)