Skip to content

Commit

Permalink
Merge branch 'main' into azure-bump-rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
sweinstein22 authored Feb 22, 2022
2 parents ffc7e67 + 846ff16 commit d9d5949
Show file tree
Hide file tree
Showing 36 changed files with 704 additions and 235 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ gem 'rfc822'
gem 'rubyzip', '>= 1.3.0'
gem 'sequel', '~> 5.53'
gem 'sequel_pg', require: 'sequel'
gem 'sinatra', '~> 2.1'
gem 'sinatra', '~> 2.2'
gem 'sinatra-contrib'
gem 'statsd-ruby', '~> 1.4.0'
gem 'steno'
Expand Down
24 changes: 12 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105)
mini_mime (1.1.2)
mini_portile2 (2.7.1)
mini_portile2 (2.8.0)
minitest (5.15.0)
ms_rest (0.6.4)
concurrent-ruby (~> 1.0)
Expand All @@ -336,12 +336,12 @@ GEM
netaddr (2.0.5)
netrc (0.11.0)
newrelic_rpm (8.4.0)
nokogiri (1.13.1)
mini_portile2 (~> 2.7.0)
nokogiri (1.13.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nokogiri (1.13.1-x86_64-darwin)
nokogiri (1.13.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.1-x86_64-linux)
nokogiri (1.13.3-x86_64-linux)
racc (~> 1.4)
oj (3.13.11)
os (1.1.4)
Expand All @@ -367,7 +367,7 @@ GEM
public_suffix (4.0.6)
racc (1.6.0)
rack (2.2.3)
rack-protection (2.1.0)
rack-protection (2.2.0)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
Expand Down Expand Up @@ -473,16 +473,16 @@ GEM
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
sinatra (2.1.0)
sinatra (2.2.0)
mustermann (~> 1.0)
rack (~> 2.2)
rack-protection (= 2.1.0)
rack-protection (= 2.2.0)
tilt (~> 2.0)
sinatra-contrib (2.1.0)
sinatra-contrib (2.2.0)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.1.0)
sinatra (= 2.1.0)
rack-protection (= 2.2.0)
sinatra (= 2.2.0)
tilt (~> 2.0)
solargraph (0.44.3)
backport (~> 1.2)
Expand Down Expand Up @@ -621,7 +621,7 @@ DEPENDENCIES
rubyzip (>= 1.3.0)
sequel (~> 5.53)
sequel_pg
sinatra (~> 2.1)
sinatra (~> 2.2)
sinatra-contrib
solargraph
spork!
Expand Down
32 changes: 32 additions & 0 deletions app/actions/route_destination_update.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module VCAP::CloudController
class RouteDestinationUpdate
class Error < StandardError
end

class << self
def update(destination, message)
validate_protocol_matches_route!(destination, message)

destination.db.transaction do
destination.lock!

destination.protocol = message.protocol if message.requested? :protocol

destination.save
end
end

private

def validate_protocol_matches_route!(destination, message)
if destination.route&.protocol == 'tcp'
unless message.protocol == 'tcp'
raise Error.new("Destination protocol must be 'tcp' if the parent route's protocol is 'tcp'")
end
elsif message.protocol == 'tcp'
raise Error.new("Destination protocol must be 'http1' or 'http2' if the parent route's protocol is 'http'")
end
end
end
end
end
6 changes: 3 additions & 3 deletions app/actions/service_credential_binding_app_create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ def precursor(service_instance, app: nil, volume_mount_services_enabled: false,
credentials: {}
}

(binding || ServiceBinding.new).tap do |b|
ServiceBinding.new.tap do |b|
ServiceBinding.db.transaction do
binding.destroy if binding
b.save_with_attributes_and_new_operation(
binding_details,
CREATE_IN_PROGRESS_OPERATION
)

MetadataUpdate.update(b, message)
end
end
Expand All @@ -62,7 +62,7 @@ def validate_service_instance!(app, service_instance, volume_mount_services_enab

def validate_binding!(binding)
if binding
already_bound! if binding.create_succeeded? || binding.create_in_progress? || binding.last_operation.nil?
already_bound! if binding.create_succeeded? || binding.create_in_progress?
incomplete_deletion! if binding.delete_failed? || binding.delete_in_progress?
end
end
Expand Down
5 changes: 3 additions & 2 deletions app/actions/service_credential_binding_key_create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ def precursor(service_instance, message:)
credentials: {}
}

(key || ServiceKey.new).tap do |b|
ServiceKey.new.tap do |b|
ServiceKey.db.transaction do
key.destroy if key
b.save_with_attributes_and_new_operation(
binding_details,
CREATE_IN_PROGRESS_OPERATION
Expand Down Expand Up @@ -59,7 +60,7 @@ def validate_service_instance!(service_instance)

def validate_key!(key, message_name)
if key
key_already_exists!(message_name) if key.create_succeeded? || key.create_in_progress? || key.last_operation.nil?
key_already_exists!(message_name) if key.create_succeeded? || key.create_in_progress?
key_incomplete_deletion!(message_name) if key.delete_failed? || key.delete_in_progress?
end
end
Expand Down
4 changes: 2 additions & 2 deletions app/actions/update_route_destinations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def update(route, to_add, to_delete, user_audit_info, manifest_triggered)
end

to_add.each do |rm|
validate_protocol_matches(rm)
validate_protocol_matches!(rm)

route_mapping = RouteMappingModel.new(rm)
route_mapping.save
Expand Down Expand Up @@ -204,7 +204,7 @@ def validate_unique!(new_route_mappings)
raise DuplicateDestinationError.new('Destinations cannot contain duplicate entries') if new_route_mappings.any? { |rm| new_route_mappings.count(rm) > 1 }
end

def validate_protocol_matches(route_destination)
def validate_protocol_matches!(route_destination)
destination_protocol = route_destination[:protocol]
return unless destination_protocol

Expand Down
22 changes: 21 additions & 1 deletion app/controllers/v3/routes_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'messages/route_create_message'
require 'messages/route_destinations_list_message'
require 'messages/route_create_message'
require 'messages/route_destination_update_message'
require 'messages/routes_list_message'
require 'messages/route_show_message'
require 'messages/route_update_message'
Expand All @@ -9,6 +10,7 @@
require 'presenters/v3/route_presenter'
require 'presenters/v3/route_destinations_presenter'
require 'presenters/v3/paginated_list_presenter'
require 'actions/route_destination_update'
require 'actions/route_create'
require 'actions/route_delete'
require 'actions/route_update'
Expand Down Expand Up @@ -144,6 +146,24 @@ def replace_destinations
unprocessable!(e.message)
end

def update_destination
message = RouteDestinationUpdateMessage.new(hashed_params[:body])
unprocessable!(message.errors.full_messages) unless message.valid?

route = Route.find(guid: hashed_params[:guid])
route_not_found! unless route && permission_queryer.can_read_route?(route.space.guid, route.organization.guid)
unauthorized! unless permission_queryer.can_manage_apps_in_space?(route.space.guid)

destination = RouteMappingModel.find(guid: hashed_params[:destination_guid])
unprocessable_destination! unless destination

RouteDestinationUpdate.update(destination, message)

render status: :ok, json: Presenters::V3::RouteDestinationPresenter.new(destination)
rescue RouteDestinationUpdate::Error => e
unprocessable!(e.message)
end

def route
@route || begin
@route = Route.find(guid: hashed_params[:guid])
Expand Down
7 changes: 3 additions & 4 deletions app/controllers/v3/service_credential_bindings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ def destroy
def details
ensure_service_credential_binding_is_accessible!
not_found! unless can_read_secrets_in_the_binding_space?
if service_credential_binding.create_in_progress? || service_credential_binding.create_failed?
not_found_with_message!(service_credential_binding)
end
not_found_with_message!(service_credential_binding) unless service_credential_binding.create_succeeded?

credentials = if service_credential_binding[:type] == 'key' && service_credential_binding.credhub_reference?
fetch_credentials_value(service_credential_binding.credhub_reference)
Expand Down Expand Up @@ -391,8 +389,9 @@ def binding_operation_in_progress!

def not_found_with_message!(service_credential_binding)
type = service_credential_binding.is_a?(ServiceKey) ? 'key' : 'binding'
operation = service_credential_binding.last_operation.type == 'create' ? 'Creation' : 'Deletion'
state = service_credential_binding.last_operation.state
resource_not_found_with_message!("Creation of service #{type} #{state}")
resource_not_found_with_message!("#{operation} of service #{type} #{state}")
end

def not_found!
Expand Down
16 changes: 13 additions & 3 deletions app/jobs/reoccurring_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module VCAP::CloudController
module Jobs
class ReoccurringJob < VCAP::CloudController::Jobs::CCJob
attr_reader :finished, :start_time
attr_reader :finished, :start_time, :retry_number

def success(current_delayed_job)
pollable_job = PollableJobModel.find_by_delayed_job(current_delayed_job)
Expand Down Expand Up @@ -49,6 +49,7 @@ def polling_interval_seconds=(interval)
def initialize
@start_time = Time.now
@finished = false
@retry_number = 0
end

def default_maximum_duration_seconds
Expand All @@ -59,8 +60,16 @@ def default_polling_interval_seconds
Config.config.get(:broker_client_default_async_poll_interval_seconds)
end

def default_polling_exponential_backoff
Config.config.get(:broker_client_async_poll_exponential_backoff_rate)
end

def next_execution_in
polling_interval_seconds * default_polling_exponential_backoff**retry_number
end

def next_enqueue_would_exceed_maximum_duration?
Time.now + polling_interval_seconds > start_time + maximum_duration_seconds
Time.now + next_execution_in > start_time + maximum_duration_seconds
end

def finish
Expand All @@ -75,9 +84,10 @@ def expire!
def enqueue_next_job(pollable_job)
opts = {
queue: Jobs::Queues.generic,
run_at: Delayed::Job.db_time_now + polling_interval_seconds
run_at: Delayed::Job.db_time_now + next_execution_in
}

@retry_number += 1
Jobs::Enqueuer.new(self, opts).enqueue_pollable(existing_guid: pollable_job.guid)
end
end
Expand Down
25 changes: 25 additions & 0 deletions app/messages/route_destination_update_message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module VCAP::CloudController
class RouteDestinationUpdateMessage < BaseMessage
def initialize(params)
super(params)
end

def self.key_requested?(key)
proc { |a| a.requested?(key) }
end

register_allowed_keys [:protocol]

validates_with NoAdditionalKeysValidator

validate :validate_protocol?, if: key_requested?(:protocol)

private

def validate_protocol?
unless protocol.is_a?(String) && RouteMappingModel::VALID_PROTOCOLS.include?(protocol)
errors.add(:destination, "protocol must be 'http1', 'http2' or 'tcp'.")
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def operation_in_progress?
end

def create_succeeded?
return true unless last_operation
return true if last_operation&.type == 'create' && last_operation.state == 'succeeded'

false
Expand Down
14 changes: 0 additions & 14 deletions app/models/services/service_binding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,6 @@ def last_operation
service_binding_operation
end

def is_created?
return true unless last_operation

if last_operation.type == 'create' && last_operation.state != 'succeeded'
return false
end

if last_operation.type == 'delete' && last_operation.state == 'succeeded'
return false
end

true
end

def save_with_attributes_and_new_operation(attributes, operation)
save_with_new_operation(operation, attributes: attributes)
self
Expand Down
2 changes: 1 addition & 1 deletion app/presenters/system_environment/system_env_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def system_env

def service_binding_env_variables
services_hash = {}
@service_bindings.select(&:is_created?).each do |service_binding|
@service_bindings.select(&:create_succeeded?).each do |service_binding|
service_name = service_binding_label(service_binding)
services_hash[service_name.to_sym] ||= []
services_hash[service_name.to_sym] << service_binding_env_values(service_binding)
Expand Down
30 changes: 29 additions & 1 deletion app/presenters/v3/route_destination_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@

module VCAP::CloudController::Presenters::V3
class RouteDestinationPresenter < BasePresenter
def initialize(
resource,
show_secrets: false,
censored_message: VCAP::CloudController::Presenters::Censorship::REDACTED_CREDENTIAL
)
super(resource, show_secrets: show_secrets, censored_message: censored_message, decorators: [])
end

def to_hash
hash = destination_hash
hash[:links] = build_links
hash
end

def destination_hash
{
guid: destination.guid,
app: {
Expand All @@ -13,12 +27,26 @@ def to_hash
},
weight: destination.weight,
port: destination.presented_port,
protocol: destination.protocol
protocol: destination.protocol,
}
end

private

def build_links
links = {
destintions: {
href: url_builder.build_url(path: "/v3/routes/#{destination.route_guid}/destinations")
},
}

links[:route] = {
href: url_builder.build_url(path: "/v3/routes/#{destination.route_guid}")
}

links
end

def destination
@resource
end
Expand Down
Loading

0 comments on commit d9d5949

Please sign in to comment.