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

Check space/org permissions by id, not guid #3021

Merged
merged 7 commits into from
Oct 28, 2022

Conversation

will-gant
Copy link
Contributor

@will-gant will-gant commented Oct 14, 2022

Thanks for contributing to cloud_controller_ng. To speed up the process of reviewing your pull request please provide us with:

A short explanation of the proposed change:

Optimizes the way controllers check user permissions by cutting out lots and lots of duplicate DB queries for spaces and orgs.

An explanation of the use cases your change solves:

Until now we've been doing something like this for a large chunk of API calls:

# app/controllers/v3/foo_controller.rb
def create
  foo = Foo.find(guid: hashed_params[:guid])
  org = foo.organization
  foo_not_found! unless @foo && permission_queryer.can_read_whatever?(org.guid)
  ...
end
# lib/cloud_controller/permissions.rb
def can_read_whatever?(org_guid)
  can_read_globally? || membership.has_any_roles?(ROLES_FOR_WHATEVER, nil, org_guid)
end
# lib/cloud_controller/membership.rb
def has_any_roles?(roles, space_guid=nil, org_guid=nil)
  org_id = Organization.where(guid: org_guid).select(:id)
  ...
end

Basically a controller action does a DB query to look up an org or a space purely so it can pass the guid of whichever it is through (ultimately) to VCAP::CloudController::Membership. The latter then uses the guid to do another DB query to look up the same row to get that thing's id. Silly.

The changes in summary:

  • Where we want to check a user's permissions in relation to a specific org or space, the controller now passes the org/space's id instead of its guid
  • Since we no longer need org guids for most permissions checks, if we've already looked up a space we can skip looking up its org in the controller entirely - rows in the spaces table have an organization_id column.
  • Fetchers. Some of these (e.g. AppFetcher) have fetch methods whose return values previously included an org. For some fetchers the org was only ever retrieved so its guid could passed for a permissions check. Such fetchers now no longer return orgs.

Links to any other associated PRs:

n/a

  • I have reviewed the contributing guide

  • I have viewed, signed, and submitted the Contributor License Agreement

  • I have made this pull request to the main branch

  • I have run all the unit tests using bundle exec rake

  • I have run CF Acceptance Tests

@will-gant will-gant force-pushed the cut-guid-lookups branch 16 times, most recently from 9a680a9 to 2417c9a Compare October 18, 2022 15:32
@will-gant
Copy link
Contributor Author

Cool, just ran this successfully through the cf-acceptance-tests (a partial run), swapping this PR in for src/cloud_controller_ng in CAPI 1.140.0. Ran the following from CATs:

apps
container_networking
detect
docker
internet_dependent
routing
service_instance_sharing
services
ssh
sso
tasks
v3

@will-gant will-gant marked this pull request as ready for review October 19, 2022 14:20
@will-gant will-gant requested a review from philippthun October 19, 2022 14:20
@philippthun philippthun self-assigned this Oct 20, 2022
Prior to this many controllers did a DB query for a space/org to retrieve its guid, which was ultimately passed to VCAP::CloudController::Membership, which would use the guid to do a DB query looking up the exact same thing so its id could be retrieved. In these cases we now retrieve the id in the first query and just pass this through.
Prior to this many controllers did a DB query for a space/org to retrieve its guid, which was ultimately passed to VCAP::CloudController::Membership, which would use the guid to do a DB query looking up the exact same thing so its id could be retrieved. In these cases we now retrieve the id in the first query and just pass this through.
app/controllers/runtime/apps_controller.rb Outdated Show resolved Hide resolved
app/controllers/v3/builds_controller.rb Outdated Show resolved Hide resolved
app/controllers/v3/builds_controller.rb Outdated Show resolved Hide resolved
app/controllers/v3/deployments_controller.rb Outdated Show resolved Hide resolved
app/controllers/v3/deployments_controller.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
@will-gant will-gant requested a review from philippthun October 25, 2022 16:37
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
spec/unit/lib/cloud_controller/permissions_spec.rb Outdated Show resolved Hide resolved
@will-gant will-gant requested a review from philippthun October 27, 2022 13:36
@philippthun philippthun merged commit 3596f0b into cloudfoundry:main Oct 28, 2022
will-gant added a commit to sap-contributions/cloud_controller_ng that referenced this pull request Dec 16, 2022
Prior to this many controllers did a DB query for a space/org to retrieve its guid, which was ultimately passed to VCAP::CloudController::Membership, which would use the guid to do a DB query looking up the exact same thing so its id could be retrieved. In these cases we now retrieve the id in the first query and just pass this through.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants