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

Refactor permissions functions #2468

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
05ca7d1
Refactor permissions functions
monamohebbi Jul 28, 2021
60465e8
Merge branch 'main' into space-supporter-refactor-2
mkocher Aug 17, 2021
677fd95
Disable Style/ConditionalAssignment cop
tjvman Aug 17, 2021
a3b7b27
build(deps-dev): bump rubocop from 1.18.3 to 1.19.0
dependabot[bot] Aug 17, 2021
135ba1b
Show when instances get rescheduled in `cf events`
Jul 17, 2021
ff7eb31
bump to 2.169.0
capi-bot Aug 18, 2021
ea60dfc
bump to 3.104.0
capi-bot Aug 18, 2021
3ff13ec
Bump v2 API docs version 2.169.0
capi-bot Aug 18, 2021
bb3f31a
Wrap all errors in delete_non_transactional_subresources
philippthun Jul 26, 2021
f7e0161
Refactor routes_controller to dedupe some logic
mkocher Jul 22, 2021
9edbfc1
Add protocols to route_destinations
mkocher Jul 22, 2021
6c588b9
Add protocol to routing_info
moleske Jul 27, 2021
cdfbca7
Refactor to make private functions idempotent
ctlong Jul 27, 2021
1fcbdd5
Add protocol to the desired LRP
ctlong Jul 27, 2021
e4343bc
Update route destination object docs with protocol
ctlong Jul 27, 2021
2542e22
Add experimental to protocol field in destination object
ctlong Jul 27, 2021
81e2576
Use slice to simplify matching route hashes
ctlong Aug 12, 2021
48200ca
Update destination object doc to reflect that protocol can be null
ctlong Aug 12, 2021
53f6424
Update route destination object description
ctlong Aug 12, 2021
23a67fe
Fix nil symbol
moleske Aug 12, 2021
86296f3
Improve the error message when protocol does not match
ctlong Aug 17, 2021
7306ceb
Refactor UpdateRouteDestinations error message on protocol uniqueness
weymanf Aug 18, 2021
c0e4ee0
Remove redundant tcp check from routing info
weymanf Aug 18, 2021
a630299
Prevent users with space supporter role reaching v2 endpoints
weymanf Jul 28, 2021
8368a88
build(deps-dev): bump listen from 3.6.0 to 3.7.0
dependabot[bot] Aug 19, 2021
7f257b6
build(deps-dev): bump rubocop from 1.19.0 to 1.19.1
dependabot[bot] Aug 19, 2021
03d00ce
Refactor routes_controller to dedupe some logic
mkocher Jul 22, 2021
399a581
Add protocols to route_destinations
mkocher Jul 22, 2021
0671eb3
Refactor to remove additional `untrusted` references
monamohebbi Aug 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ Style/BlockDelimiters:
Style/ClassAndModuleChildren:
Enabled: false

Style/ConditionalAssignment:
Enabled: false

Style/Documentation:
Enabled: false

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ group :test do
gem 'rspec-rails', '~> 5.0.2'
gem 'rspec-wait'
gem 'rspec_api_documentation', '>= 6.1.0'
gem 'rubocop', '~> 1.18.3'
gem 'rubocop', '~> 1.19.1'
gem 'timecop'
gem 'webmock', '> 2.3.1'
end
Expand Down
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ GEM
addressable (~> 2.0)
excon
http (>= 2.0, < 5.0)
listen (3.6.0)
listen (3.7.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loggregator_emitter (5.2.0)
Expand Down Expand Up @@ -404,13 +404,13 @@ GEM
activesupport (>= 3.0.0)
mustache (~> 1.0, >= 0.99.4)
rspec (~> 3.0)
rubocop (1.18.3)
rubocop (1.19.1)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.7.0, < 2.0)
rubocop-ast (>= 1.9.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.10.0)
Expand Down Expand Up @@ -572,7 +572,7 @@ DEPENDENCIES
rspec-rails (~> 5.0.2)
rspec-wait
rspec_api_documentation (>= 6.1.0)
rubocop (~> 1.18.3)
rubocop (~> 1.19.1)
ruby-debug-ide (>= 0.7.0.beta4)
rubyzip (>= 1.3.0)
sequel (~> 5.47)
Expand Down
11 changes: 2 additions & 9 deletions app/actions/app_delete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ def delete(apps, record_event: true)
apps.each do |app|
logger.info("Deleting app: #{app.guid}")

errs = delete_non_transactional_subresources(app)

if errs&.any?
raise SubResourceError.new(errs)
end
delete_non_transactional_subresources(app)

app.db.transaction do
app.lock!
Expand Down Expand Up @@ -104,10 +100,7 @@ def delete_subresources(app)

def delete_non_transactional_subresources(app)
errors = delete_bindings(app.service_bindings, user_audit_info: @user_audit_info)
non_async_errors = errors.reject { |e| e.is_a?(AsyncBindingDeletionsTriggered) }
raise non_async_errors.first unless non_async_errors.empty?

errors
raise SubResourceError.new(errors) if errors.any?
end

def stagers
Expand Down
52 changes: 49 additions & 3 deletions app/actions/update_route_destinations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class << self
def add(new_route_mappings, route, apps_hash, user_audit_info, manifest_triggered: false)
existing_route_mappings = route_to_mapping_hashes(route)
new_route_mappings = update_port(new_route_mappings, apps_hash)
new_route_mappings = update_protocol(new_route_mappings, route)
new_route_mappings = add_route(new_route_mappings, route)

validate_max_destinations!(existing_route_mappings, new_route_mappings)
Expand All @@ -21,14 +22,15 @@ def add(new_route_mappings, route, apps_hash, user_audit_info, manifest_triggere
raise Error.new('Destinations cannot be inserted when there are weighted destinations already configured.')
end

to_add = new_route_mappings - existing_route_mappings
to_add = compare_destination_hashes(new_route_mappings, existing_route_mappings)

update(route, to_add, [], user_audit_info, manifest_triggered)
end

def replace(new_route_mappings, route, apps_hash, user_audit_info, manifest_triggered: false)
existing_route_mappings = route_to_mapping_hashes(route)
new_route_mappings = update_port(new_route_mappings, apps_hash)
new_route_mappings = update_protocol(new_route_mappings, route)
new_route_mappings = add_route(new_route_mappings, route)

validate_max_destinations!([], new_route_mappings)
Expand Down Expand Up @@ -57,7 +59,8 @@ def update(route, to_add, to_delete, user_audit_info, manifest_triggered)
processes_to_ports_map = {}

to_delete.each do |rm|
route_mapping = RouteMappingModel.find(rm)
rm.delete(:protocol)
route_mapping = RouteMappingModel[rm]
route_mapping.destroy

Copilot::Adapter.unmap_route(route_mapping)
Expand All @@ -76,6 +79,8 @@ def update(route, to_add, to_delete, user_audit_info, manifest_triggered)
end

to_add.each do |rm|
validate_protocol_matches(rm)

route_mapping = RouteMappingModel.new(rm)
route_mapping.save

Expand Down Expand Up @@ -126,6 +131,23 @@ def update_processes(processes_to_ports_map)
raise Error.new(e.message)
end

def compare_destination_hashes(new_route_mappings, existing_route_mappings)
new_route_mappings.reject do |new|
matching_route_mapping = existing_route_mappings.find do |existing|
new[:app_guid] == existing[:app_guid] &&
new[:process_type] == existing[:process_type] &&
new[:route_guid] == existing[:route_guid] &&
new[:app_port] == existing[:app_port]
end

if matching_route_mapping && matching_route_mapping[:protocol] != new[:protocol]
raise Error.new('Destination exists with conflicting protocol')
end

matching_route_mapping
end
end

def add_route(destinations, route)
destinations.map do |dst|
dst.merge({ route: route, route_guid: route.guid })
Expand All @@ -142,6 +164,14 @@ def update_port(destinations, apps_hash)
end
end

def update_protocol(destinations, route)
destinations.each do |dst|
if dst[:protocol].nil?
dst[:protocol] = RouteMappingModel::DEFAULT_PROTOCOL_MAPPING[route.protocol]
end
end
end

def default_port(app)
if app.buildpack?
ProcessModel::DEFAULT_HTTP_PORT
Expand All @@ -163,7 +193,8 @@ def destination_to_mapping_hash(route, destination)
process_type: destination.process_type,
app_port: destination.app_port,
route: route,
weight: destination.weight
weight: destination.weight,
protocol: destination.protocol_without_defaults
}
end

Expand All @@ -175,6 +206,21 @@ 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)
destination_protocol = route_destination[:protocol]
return unless destination_protocol

route_protocol = route_destination[:route].protocol
dest_to_route_map = { 'tcp' => 'tcp', 'http1' => 'http', 'http2' => 'http' }

raise protocol_mismatch_error(route_protocol, destination_protocol) if route_protocol != dest_to_route_map[destination_protocol]
end

def protocol_mismatch_error(route_protocol, destination_protocol)
valid_options = { 'tcp' => 'tcp', 'http' => 'http1, http2' }
Error.new("Cannot use '#{destination_protocol}' protocol for #{route_protocol} routes; valid options are: [#{valid_options[route_protocol]}].")
end

def validate_max_destinations!(existing_route_mappings, new_route_mappings)
total_route_mapping_count = existing_route_mappings.count + new_route_mappings.count

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/internal/app_crashed_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def crashed(process_guid)
crash_payload['version'] = Diego::ProcessGuid.cc_process_version(process_guid)

Repositories::ProcessEventRepository.record_crash(process, crash_payload)
Repositories::AppEventRepository.new.create_app_exit_event(process, crash_payload)
Repositories::AppEventRepository.new.create_app_crash_event(process, crash_payload)
end

private
Expand Down
39 changes: 39 additions & 0 deletions app/controllers/internal/app_rescheduling_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'sinatra'
require 'controllers/base/base_controller'
require 'cloud_controller/internal_api'

module VCAP::CloudController
class AppReschedulingController < RestController::BaseController
# Endpoint does its own (non-standard) auth
allow_unauthenticated_access

post '/internal/v4/apps/:process_guid/rescheduling', :rescheduling
def rescheduling(process_guid)
rescheduling_payload = rescheduling_request

app_guid = Diego::ProcessGuid.cc_process_guid(process_guid)

process = ProcessModel.find(guid: app_guid)
raise CloudController::Errors::NotFound.new_from_details('ProcessNotFound', app_guid) unless process

rescheduling_payload['version'] = Diego::ProcessGuid.cc_process_version(process_guid)

Repositories::ProcessEventRepository.record_rescheduling(process, rescheduling_payload)
end

private

def rescheduling_request
rescheduling = {}
begin
payload = body.read
rescheduling = MultiJson.load(payload)
rescue MultiJson::ParseError => pe
logger.error('diego.app_rescheduling.parse-error', payload: payload, error: pe.to_s)
raise CloudController::Errors::ApiError.new_from_details('MessageParseError', payload)
end

rescheduling
end
end
end
10 changes: 5 additions & 5 deletions app/controllers/v3/app_features_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AppFeaturesController < ApplicationController

def index
app, space, org = AppFetcher.new.fetch(hashed_params[:app_guid])
app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)
resources = presented_app_features(app)

render status: :ok, json: {
Expand All @@ -28,7 +28,7 @@ def index

def show
app, space, org = AppFetcher.new.fetch(hashed_params[:app_guid])
app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)
resource_not_found!(:feature) unless APP_FEATURES.include?(hashed_params[:name])

render status: :ok, json: feature_presenter_for(hashed_params[:name], app)
Expand All @@ -37,12 +37,12 @@ def show
def update
app, space, org = AppFetcher.new.fetch(hashed_params[:app_guid])

app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)

name = hashed_params[:name]
resource_not_found!(:feature) unless APP_FEATURES.include?(name)
if UNTRUSTED_APP_FEATURES.include?(name)
unauthorized! unless permission_queryer.untrusted_can_write_to_space?(space.guid)
unauthorized! unless permission_queryer.can_manage_apps_in_space?(space.guid)
else
unauthorized! unless permission_queryer.can_write_to_space?(space.guid)
end
Expand All @@ -57,7 +57,7 @@ def update
def ssh_enabled
app, space, org = AppFetcher.new.fetch(hashed_params[:guid])

app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)

render status: :ok, json: Presenters::V3::AppSshStatusPresenter.new(app, Config.config.get(:allow_app_ssh_access))
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/v3/app_manifests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class AppManifestsController < ApplicationController
def show
app, space, org = AppFetcher.new.fetch(hashed_params[:guid])

app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)
unauthorized! unless permission_queryer.can_read_secrets_in_space?(space.guid, org.guid)

manifest_presenter = Presenters::V3::AppManifestPresenter.new(app, app.service_bindings, app.routes)
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/v3/app_revisions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def index
invalid_param!(message.errors.full_messages) unless message.valid?

app, space, org = AppFetcher.new.fetch(hashed_params[:guid])
app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)

dataset = AppRevisionsListFetcher.fetch(app, message)

Expand All @@ -31,7 +31,7 @@ def deployed
invalid_param!(message.errors.full_messages) unless message.valid?

app, space, org = AppFetcher.new.fetch(hashed_params[:guid])
app_not_found! unless app && permission_queryer.untrusted_can_read_from_space?(space.guid, org.guid)
app_not_found! unless app && permission_queryer.can_read_from_space?(space.guid, org.guid)

dataset = AppRevisionsListFetcher.fetch_deployed(app)

Expand Down
Loading