Skip to content

Commit 625dd2b

Browse files
committed
wip: Implement lb_algo mapping to loadbalancing-algorithm in manifest
1 parent a79de51 commit 625dd2b

File tree

5 files changed

+82
-9
lines changed

5 files changed

+82
-9
lines changed

app/actions/manifest_route_update.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def update(app_guid, message, user_audit_info)
5757

5858
private
5959

60+
## TODO: We also need to update when the route options differ
6061
def find_or_create_valid_route(app, manifest_route, user_audit_info)
6162
manifest_route[:candidate_host_domain_pairs].each do |candidate|
6263
potential_domain = candidate[:domain]
@@ -81,7 +82,8 @@ def find_or_create_valid_route(app, manifest_route, user_audit_info)
8182
message = RouteCreateMessage.new({
8283
'host' => host,
8384
'path' => manifest_route[:path],
84-
'port' => manifest_route[:port]
85+
'port' => manifest_route[:port],
86+
'options' => manifest_route[:options]
8587
})
8688

8789
route = RouteCreate.new(user_audit_info).create(

app/messages/manifest_routes_update_message.rb

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,20 @@ class ManifestRoutesUpdateMessage < BaseMessage
77

88
class ManifestRoutesYAMLValidator < ActiveModel::Validator
99
def validate(record)
10-
return unless is_not_array?(record.routes) || contains_non_route_hash_values?(record.routes)
11-
12-
record.errors.add(:routes, message: 'must be a list of route objects')
10+
if is_not_array?(record.routes) || contains_non_route_hash_values?(record.routes)
11+
record.errors.add(:routes, message: 'must be a list of route objects')
12+
return
13+
end
14+
15+
if contains_invalid_route_options?(record.routes)
16+
record.errors.add(:routes, message: 'contains invalid route options')
17+
return
18+
end
19+
20+
if contains_invalid_lb_algo?(record.routes)
21+
record.errors.add(:routes, message: 'contains an invalid loadbalancing-algorithm option')
22+
return
23+
end
1324
end
1425

1526
def is_not_array?(routes)
@@ -19,6 +30,22 @@ def is_not_array?(routes)
1930
def contains_non_route_hash_values?(routes)
2031
routes.any? { |r| !(r.is_a?(Hash) && r[:route].present?) }
2132
end
33+
34+
def contains_invalid_route_options?(routes)
35+
routes.any? do |r|
36+
next unless r[:options]
37+
38+
return true unless r[:options].is_a?(Hash)
39+
end
40+
end
41+
42+
def contains_invalid_lb_algo?(routes)
43+
routes.any? do |r|
44+
next unless r[:options] && r[:options][:'loadbalancing-algorithm']
45+
46+
return true if r[:options][:'loadbalancing-algorithm'] && %w[round-robin least-connections].exclude?(r[:options][:'loadbalancing-algorithm'])
47+
end
48+
end
2249
end
2350

2451
validates_with NoAdditionalKeysValidator
@@ -33,7 +60,7 @@ def contains_non_route_hash_values?(routes)
3360
def manifest_route_mappings
3461
@manifest_route_mappings ||= routes.map do |route|
3562
{
36-
route: ManifestRoute.parse(route[:route]),
63+
route: ManifestRoute.parse(route[:route], route[:options]),
3764
protocol: route[:protocol]
3865
}
3966
end

app/presenters/v3/app_manifest_presenters/route_properties_presenter.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ module AppManifestPresenters
55
class RoutePropertiesPresenter
66
def to_hash(route_mappings:, app:, **_)
77
route_hashes = route_mappings.map do |route_mapping|
8-
{
8+
route_hash = {
99
route: route_mapping.route.uri,
1010
protocol: route_mapping.protocol
1111
}
12+
13+
route_hash[:options] = route_mapping.route.options if route_mapping.route.options && route_mapping.route.options[:lb_algo]
14+
15+
route_hash
1216
end
1317

1418
{ routes: alphabetize(route_hashes).presence }

lib/cloud_controller/app_manifest/manifest_route.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,22 @@ class ManifestRoute
66
SUPPORTED_TCP_SCHEMES = %w[tcp unspecified].freeze
77
WILDCARD_HOST = '*'.freeze
88

9-
def self.parse(string)
10-
parsed_uri = Addressable::URI.heuristic_parse(string, scheme: 'unspecified')
9+
def self.parse(route, options=nil)
10+
parsed_uri = Addressable::URI.heuristic_parse(route, scheme: 'unspecified')
1111

1212
attrs = if parsed_uri.nil?
1313
{}
1414
else
1515
parsed_uri.to_hash
1616
end
1717

18-
attrs[:full_route] = string
18+
attrs[:full_route] = route
19+
20+
if options
21+
attrs[:options] = {}
22+
attrs[:options][:lb_algo] = options[:'loadbalancing-algorithm'] if options[:'loadbalancing-algorithm']
23+
end
24+
1925
ManifestRoute.new(attrs)
2026
end
2127

spec/unit/messages/manifest_routes_update_message_spec.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,40 @@ module VCAP::CloudController
208208
expect(msg.errors.full_messages).to include("Route protocol must be 'http1', 'http2' or 'tcp'.")
209209
end
210210
end
211+
212+
context 'when a route contains empty route options' do
213+
let(:body) do
214+
{ 'routes' =>
215+
[
216+
{ 'route' => 'existing.example.com',
217+
'options' => {} }
218+
] }
219+
end
220+
221+
it 'returns true' do
222+
msg = ManifestRoutesUpdateMessage.new(body)
223+
224+
expect(msg.valid?).to be(true)
225+
end
226+
end
227+
228+
context 'when a route contains a valid loadbalancing-algorithm' do
229+
let(:body) do
230+
{ 'routes' =>
231+
[
232+
{ 'route' => 'existing.example.com',
233+
'options' => {
234+
'loadbalancing-algorithm' => 'round-robin'
235+
} }
236+
] }
237+
end
238+
239+
it 'returns true' do
240+
msg = ManifestRoutesUpdateMessage.new(body)
241+
242+
expect(msg.valid?).to be(true)
243+
end
244+
end
211245
end
212246
end
213247
end

0 commit comments

Comments
 (0)