Skip to content

Commit 4c0759a

Browse files
a18ehoffmaen
authored andcommitted
Adjust behaviour to new decisions:
options default: {} API: options is not nullable specific option is additive specific option is nullable empty hash does not change anything (additive) get empty options -> {} manifest: options and specific option is nullable, but no-op
1 parent 52f1a38 commit 4c0759a

22 files changed

+228
-132
lines changed

app/actions/manifest_route_update.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,15 @@ def find_or_create_valid_route(app, manifest_route, user_audit_info)
9292
domain: existing_domain,
9393
manifest_triggered: true
9494
)
95+
elsif route.space.guid != app.space_guid
96+
raise InvalidRoute.new('Routes cannot be mapped to destinations in different spaces')
9597
elsif manifest_route[:options] && route[:options] != manifest_route[:options]
9698
# remove nil values from options
9799
manifest_route[:options] = manifest_route[:options].compact
98100
message = RouteUpdateMessage.new({
99101
'options' => manifest_route[:options]
100102
})
101103
route = RouteUpdate.new.update(route:, message:)
102-
103-
elsif route.space.guid != app.space_guid
104-
raise InvalidRoute.new('Routes cannot be mapped to destinations in different spaces')
105104
end
106105

107106
return route

app/actions/route_create.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def create(message:, space:, domain:, manifest_triggered: false)
1616
port: port(message, domain),
1717
space: space,
1818
domain: domain,
19-
options: message.options
19+
options: message.options.nil? ? {} : message.options.compact
2020
)
2121

2222
Route.db.transaction do

app/actions/route_update.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ def update(route:, message:)
44
Route.db.transaction do
55
if message.requested?(:options)
66
route.options = if message.options.nil?
7-
nil
8-
elsif route.options.nil?
9-
message.options
7+
{}
108
else
11-
route.options.merge(message.options)
9+
route.options.symbolize_keys.merge(message.options).compact
1210
end
1311
end
1412

app/messages/manifest_routes_update_message.rb

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,8 @@ def validate(record)
1313
return
1414
end
1515

16-
if contains_invalid_route_options?(record.routes)
17-
record.errors.add(:routes, message: 'contains invalid route options')
18-
return
19-
end
20-
21-
return unless contains_invalid_lb_algo?(record.routes)
22-
23-
record.errors.add(:routes, message: 'contains an invalid loadbalancing-algorithm option')
16+
contains_invalid_route_options?(record)
17+
contains_invalid_lb_algo?(record)
2418
nil
2519
end
2620

@@ -32,23 +26,34 @@ def contains_non_route_hash_values?(routes)
3226
routes.any? { |r| !(r.is_a?(Hash) && r[:route].present?) }
3327
end
3428

35-
def contains_invalid_route_options?(routes)
29+
def contains_invalid_route_options?(record)
30+
routes = record.routes
3631
routes.any? do |r|
3732
next unless r[:options]
3833

3934
return true unless r[:options].is_a?(Hash)
4035

4136
return false if r[:options].empty?
4237

43-
return r[:options].keys.all? { |key| RouteOptionsMessage::VALID_MANIFEST_ROUTE_OPTIONS.exclude?(key) }
38+
r[:options].each_key do |key|
39+
RouteOptionsMessage::VALID_MANIFEST_ROUTE_OPTIONS.exclude?(key) &&
40+
record.errors.add(:base,
41+
message: "Route '#{r[:route]}' contains invalid route option '#{key}'. \
42+
Valid keys: '#{RouteOptionsMessage::VALID_MANIFEST_ROUTE_OPTIONS.join(', ')}'")
43+
end
4444
end
4545
end
4646

47-
def contains_invalid_lb_algo?(routes)
48-
routes.any? do |r|
47+
def contains_invalid_lb_algo?(record)
48+
routes = record.routes
49+
routes.each do |r|
4950
next unless r[:options] && r[:options][:'loadbalancing-algorithm']
5051

51-
return true if r[:options][:'loadbalancing-algorithm'] && RouteOptionsMessage::VALID_LOADBALANCING_ALGORITHMS.exclude?(r[:options][:'loadbalancing-algorithm'])
52+
lb_algo = r[:options][:'loadbalancing-algorithm']
53+
RouteOptionsMessage::VALID_LOADBALANCING_ALGORITHMS.exclude?(lb_algo) &&
54+
record.errors.add(:base,
55+
message: "Route '#{r[:route]}' contains invalid load-balancing algorithm '#{lb_algo}'. \
56+
Valid algorithms: '#{RouteOptionsMessage::VALID_LOADBALANCING_ALGORITHMS.join(', ')}'")
5257
end
5358
end
5459
end

app/messages/route_create_message.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class RouteCreateMessage < MetadataBaseMessage
1414
options
1515
]
1616

17+
def self.options_requested?
18+
@options_requested ||= proc { |a| a.requested?(:options) }
19+
end
20+
1721
validates :host,
1822
allow_nil: true,
1923
string: true,
@@ -58,7 +62,7 @@ class RouteCreateMessage < MetadataBaseMessage
5862

5963
validates_with NoAdditionalKeysValidator
6064
validates_with RelationshipValidator
61-
validates_with OptionsValidator
65+
validates_with OptionsValidator, if: options_requested?
6266

6367
delegate :space_guid, to: :relationships_message
6468
delegate :domain_guid, to: :relationships_message

app/messages/route_options_message.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class RouteOptionsMessage < BaseMessage
66
VALID_ROUTE_OPTIONS = %i[lb_algo].freeze
77
VALID_LOADBALANCING_ALGORITHMS = %w[round-robin least-connections].freeze
88

9-
register_allowed_keys %i[lb_algo]
9+
register_allowed_keys VALID_ROUTE_OPTIONS
1010
validates_with NoAdditionalKeysValidator
1111
validates :lb_algo,
1212
inclusion: { in: VALID_LOADBALANCING_ALGORITHMS, message: "'%<value>s' is not a supported load-balancing algorithm" },

app/messages/validators.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,6 @@ def validate(record)
242242

243243
class OptionsValidator < ActiveModel::Validator
244244
def validate(record)
245-
# Empty option hashes are allowed, so we skip further validation
246-
record.options.blank? && return
247-
248245
unless record.options.is_a?(Hash)
249246
record.errors.add(:options, message: "'options' is not a valid object")
250247
return

db/migrations/20241105000000_add_options_to_route.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
Sequel.migration do
22
up do
33
alter_table(:routes) do
4-
# rubocop:disable Migration/IncludeStringSize
5-
add_column :options, String, text: true, default: nil
6-
# rubocop:enable Migration/IncludeStringSize
4+
add_column :options, String, size: 4096, default: '{}'
75
end
86
end
97
down do

lib/cloud_controller/app_manifest/manifest_route.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,16 @@ def self.parse(route, options=nil)
1616
end
1717

1818
attrs[:full_route] = route
19-
20-
if options
21-
attrs[:options] = {}
22-
attrs[:options][:lb_algo] = options[:'loadbalancing-algorithm'] if options.key?(:'loadbalancing-algorithm')
23-
end
19+
attrs[:options] = {}
20+
attrs[:options][:lb_algo] = options[:'loadbalancing-algorithm'] if options && options.key?(:'loadbalancing-algorithm')
2421

2522
ManifestRoute.new(attrs)
2623
end
2724

2825
def valid?
2926
if @attrs[:options] && !@attrs[:options].empty?
3027
return false if @attrs[:options].keys.any? { |key| RouteOptionsMessage::VALID_ROUTE_OPTIONS.exclude?(key) }
28+
# validation for loadbalancing algorithm
3129
return false if @attrs[:options][:lb_algo] && RouteOptionsMessage::VALID_LOADBALANCING_ALGORITHMS.exclude?(@attrs[:options][:lb_algo])
3230
end
3331

spec/request/app_manifests_spec.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,13 @@
9797
'routes' => [
9898
{
9999
'route' => "#{route.host}.#{route.domain.name}",
100-
'protocol' => 'http1'
100+
'protocol' => 'http1',
101+
'options' => {}
101102
},
102103
{
103104
'route' => "#{second_route.host}.#{second_route.domain.name}/path",
104-
'protocol' => 'http1'
105+
'protocol' => 'http1',
106+
'options' => {}
105107
}
106108
],
107109
'metadata' => { 'labels' => { 'potato' => 'idaho' }, 'annotations' => { 'style' => 'mashed' } },
@@ -201,11 +203,13 @@
201203
'routes' => [
202204
{
203205
'route' => "#{route.host}.#{route.domain.name}",
204-
'protocol' => 'http1'
206+
'protocol' => 'http1',
207+
'options' => {}
205208
},
206209
{
207210
'route' => "#{second_route.host}.#{second_route.domain.name}/path",
208-
'protocol' => 'http1'
211+
'protocol' => 'http1',
212+
'options' => {}
209213
}
210214
],
211215
'metadata' => { 'labels' => { 'potato' => 'idaho' }, 'annotations' => { 'style' => 'mashed' } },
@@ -273,11 +277,13 @@
273277
'routes' => [
274278
{
275279
'route' => "#{route.host}.#{route.domain.name}",
276-
'protocol' => 'http2'
280+
'protocol' => 'http2',
281+
'options' => {}
277282
},
278283
{
279284
'route' => "#{second_route.host}.#{second_route.domain.name}/path",
280-
'protocol' => 'http1'
285+
'protocol' => 'http1',
286+
'options' => {}
281287
}
282288
]
283289
}

0 commit comments

Comments
 (0)