Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit 3b6ccfc

Browse files
author
Brian Butz
authored
v3(services): Return list of service credential bindings (cloudfoundry#1761)
* v3(services): Return list of service credential bindings [#173171550](https://www.pivotaltracker.com/story/show/173171550)
1 parent 214fda4 commit 3b6ccfc

18 files changed

Lines changed: 429 additions & 116 deletions

.rspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
--color
22
--order rand
3+
-I app
Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,65 @@
11
require 'fetchers/service_credential_binding_fetcher'
2+
require 'fetchers/service_credential_binding_list_fetcher'
3+
require 'presenters/v3/service_credential_binding_presenter'
24

35
class ServiceCredentialBindingsController < ApplicationController
4-
before_action :ensure_service_credential_binding_exists!
5-
before_action :ensure_user_has_access!
6+
def index
7+
results = list_fetcher.fetch(space_guids: space_guids)
8+
9+
presenter = Presenters::V3::PaginatedListPresenter.new(
10+
presenter: Presenters::V3::ServiceCredentialBindingPresenter,
11+
paginated_result: SequelPaginator.new.get_page(results, pagination_options),
12+
path: '/v3' + service_credential_bindings_path
13+
)
14+
15+
render status: :ok, json: presenter
16+
end
617

718
def show
19+
ensure_service_credential_binding_is_accessible!
820
render status: :ok, json: serialized
921
end
1022

1123
private
1224

13-
def serialized
14-
{
15-
guid: service_credential_binding.guid,
16-
type: service_credential_binding.type
17-
}
25+
def service_credential_binding
26+
@service_credential_binding ||= fetcher.fetch(hashed_params[:guid], space_guids: space_guids)
1827
end
1928

20-
def ensure_service_credential_binding_exists!
21-
not_found! unless service_credential_binding_exists?
29+
def space_guids
30+
if permission_queryer.can_read_globally?
31+
:all
32+
else
33+
permission_queryer.readable_space_guids
34+
end
2235
end
2336

24-
def ensure_user_has_access!
25-
not_found! unless allowed_to_access_space?
37+
def pagination_options
38+
query_params_with_order_by = query_params.reverse_merge(order_by: :created_at)
39+
ListMessage.from_params(query_params_with_order_by, []).pagination_options
2640
end
2741

28-
def not_found!
29-
resource_not_found!(:service_credential_binding)
42+
def serialized
43+
Presenters::V3::ServiceCredentialBindingPresenter.new(service_credential_binding).to_hash
3044
end
3145

32-
def service_credential_binding
33-
@service_credential_binding ||= fetcher.fetch(hashed_params[:guid])
46+
def ensure_service_credential_binding_is_accessible!
47+
not_found! unless service_credential_binding_exists?
3448
end
3549

36-
def fetcher
37-
@fetcher ||= VCAP::CloudController::ServiceCredentialBindingFetcher.new
50+
def not_found!
51+
resource_not_found!(:service_credential_binding)
3852
end
3953

4054
def service_credential_binding_exists?
4155
!!service_credential_binding
4256
end
4357

44-
def allowed_to_access_space?
45-
space = service_credential_binding.space
58+
def list_fetcher
59+
@list_fetcher ||= VCAP::CloudController::ServiceCredentialBindingListFetcher.new
60+
end
4661

47-
permission_queryer.can_read_from_space?(space.guid, space.organization_guid)
62+
def fetcher
63+
@fetcher ||= VCAP::CloudController::ServiceCredentialBindingFetcher.new
4864
end
4965
end
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
module VCAP
22
module CloudController
33
class ServiceCredentialBindingFetcher
4-
ServiceInstanceCredential = Struct.new(:guid, :type, :space).freeze
4+
ServiceInstanceCredential = Struct.new(:guid, :type).freeze
55

6-
def fetch(guid)
7-
ServiceCredentialBinding::View.first(guid: guid).try do |db_binding|
6+
def fetch(guid, space_guids:)
7+
list_fetcher.fetch(space_guids: space_guids).first(guid: guid).try do |db_binding|
88
ServiceInstanceCredential.new(
99
db_binding.guid,
10-
db_binding.type,
11-
db_binding.space
10+
db_binding.type
1211
)
1312
end
1413
end
14+
15+
private
16+
17+
def list_fetcher
18+
ServiceCredentialBindingListFetcher.new
19+
end
1520
end
1621
end
1722
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module VCAP
2+
module CloudController
3+
class ServiceCredentialBindingListFetcher
4+
def fetch(space_guids:)
5+
case space_guids
6+
when :all
7+
ServiceCredentialBinding::View.dataset
8+
else
9+
ServiceCredentialBinding::View.where { Sequel[:space_guid] =~ space_guids }
10+
end
11+
end
12+
end
13+
end
14+
end

app/models/services/service_credential_binding_view.rb

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ module Types
66
SERVICE_BINDING = 'app'.freeze
77
end
88

9-
SERVICE_KEY_VIEW = VCAP::CloudController::ServiceKey.select(
10-
:guid,
9+
SERVICE_KEY_VIEW = Sequel::Model(:service_keys).select(
10+
Sequel.as(:service_keys__guid, :guid),
1111
Sequel.as(Types::SERVICE_KEY, :type),
12-
:service_instance_id,
13-
Sequel.as(nil, :app_guid)
12+
Sequel.as(:spaces__guid, :space_guid),
13+
Sequel.as(:service_keys__created_at, :created_at)
14+
).join(
15+
:service_instances, id: Sequel[:service_keys][:service_instance_id]
16+
).join(
17+
:spaces, id: Sequel[:service_instances][:space_id]
1418
).freeze
1519

16-
SERVICE_BINDING_VIEW = VCAP::CloudController::ServiceBinding.select(
17-
:guid,
20+
SERVICE_BINDING_VIEW = Sequel::Model(:service_bindings).select(
21+
Sequel.as(:service_bindings__guid, :guid),
1822
Sequel.as(Types::SERVICE_BINDING, :type),
19-
Sequel.as(nil, :service_instance_id),
20-
:app_guid
23+
Sequel.as(:spaces__guid, :space_guid),
24+
Sequel.as(:service_bindings__created_at, :created_at)
25+
).join(
26+
:apps, guid: Sequel[:service_bindings][:app_guid]
27+
).join(
28+
:spaces, guid: Sequel[:apps][:space_guid]
2129
).freeze
2230

2331
VIEW = [
@@ -28,20 +36,6 @@ module Types
2836
end.from_self.freeze
2937

3038
class View < Sequel::Model(VIEW)
31-
many_to_one :service_instance, class: 'VCAP::CloudController::ServiceInstance'
32-
many_to_one :app, class: 'VCAP::CloudController::AppModel', key: :app_guid, primary_key: :guid, without_guid_generation: true
33-
34-
def space
35-
relation =
36-
case type
37-
when Types::SERVICE_BINDING
38-
app
39-
else
40-
service_instance
41-
end
42-
43-
relation.space
44-
end
4539
end
4640
end
4741
end
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
module VCAP::CloudController
2-
module Presenters
3-
module Censorship
4-
PRIVATE_DATA_HIDDEN = '[PRIVATE DATA HIDDEN]'.freeze
5-
PRIVATE_DATA_HIDDEN_LIST = '[PRIVATE DATA HIDDEN IN LISTS]'.freeze
6-
REDACTED = '[REDACTED]'.freeze
7-
REDACTED_CREDENTIAL = '***'.freeze
1+
module VCAP
2+
module CloudController
3+
module Presenters
4+
module Censorship
5+
PRIVATE_DATA_HIDDEN = '[PRIVATE DATA HIDDEN]'.freeze
6+
PRIVATE_DATA_HIDDEN_LIST = '[PRIVATE DATA HIDDEN IN LISTS]'.freeze
7+
REDACTED = '[REDACTED]'.freeze
8+
REDACTED_CREDENTIAL = '***'.freeze
9+
end
810
end
911
end
1012
end

app/presenters/v3/base_presenter.rb

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
require 'presenters/helpers/censorship'
22

3-
module VCAP::CloudController
4-
module Presenters
5-
module V3
6-
class BasePresenter
7-
def initialize(resource, show_secrets: true, censored_message: Censorship::PRIVATE_DATA_HIDDEN, decorators: [])
8-
@resource = resource
9-
@show_secrets = show_secrets
10-
@censored_message = censored_message
11-
@decorators = decorators
12-
end
3+
module VCAP
4+
module CloudController
5+
module Presenters
6+
module V3
7+
class BasePresenter
8+
def initialize(resource, show_secrets: true, censored_message: Censorship::PRIVATE_DATA_HIDDEN, decorators: [])
9+
@resource = resource
10+
@show_secrets = show_secrets
11+
@censored_message = censored_message
12+
@decorators = decorators
13+
end
1314

14-
private
15+
private
1516

16-
def redact(unredacted_value)
17-
@show_secrets ? unredacted_value : @censored_message
18-
end
17+
def redact(unredacted_value)
18+
@show_secrets ? unredacted_value : @censored_message
19+
end
1920

20-
def redact_hash(unredacted_value)
21-
@show_secrets ? unredacted_value : { 'redacted_message' => @censored_message }
22-
end
21+
def redact_hash(unredacted_value)
22+
@show_secrets ? unredacted_value : { 'redacted_message' => @censored_message }
23+
end
2324

24-
def url_builder
25-
@url_builder ||= VCAP::CloudController::Presenters::ApiUrlBuilder
25+
def url_builder
26+
@url_builder ||= VCAP::CloudController::Presenters::ApiUrlBuilder
27+
end
2628
end
2729
end
2830
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require_relative 'base_presenter'
2+
3+
module VCAP
4+
module CloudController
5+
module Presenters
6+
module V3
7+
class ServiceCredentialBindingPresenter < BasePresenter
8+
def to_hash
9+
{
10+
guid: @resource.guid,
11+
type: @resource.type
12+
}
13+
end
14+
end
15+
end
16+
end
17+
end
18+
end

config/routes.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@
185185
delete '/service_bindings/:guid', to: 'service_bindings#destroy'
186186

187187
# service_credential_bindings
188-
get '/service_credential_bindings/:guid', to: 'service_credential_bindings#show'
188+
resources :service_credential_bindings,
189+
param: :guid,
190+
only: [:show, :index]
189191

190192
# service_brokers
191193
get '/service_brokers', to: 'service_brokers#index'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<% content_for :single_service_credential_binding_app do %>
2+
{
3+
"guid": "ddd7fb26-c42d-4acf-a035-60fdd094a167",
4+
"type": "app"
5+
}
6+
<% end %>
7+
8+
<% content_for :single_service_credential_binding_key do %>
9+
{
10+
"guid": "ddd7fb26-c42d-4acf-a035-60fdd094a167",
11+
"type": "key"
12+
}
13+
<% end %>
14+
15+
<% content_for :paginated_list_of_service_credential_bindings do |base_url| %>
16+
{
17+
"pagination": {
18+
"total_results": 3,
19+
"total_pages": 2,
20+
"first": {
21+
"href": "https://api.example.org<%= base_url %>?page=1&per_page=2"
22+
},
23+
"last": {
24+
"href": "https://api.example.org<%= base_url %>?page=2&per_page=2"
25+
},
26+
"next": {
27+
"href": "https://api.example.org<%= base_url %>?page=2&per_page=2"
28+
},
29+
"previous": null
30+
},
31+
"resources": [
32+
{
33+
"guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3",
34+
"type": "app"
35+
},
36+
{
37+
"guid": "7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62",
38+
"type": "key"
39+
}
40+
]
41+
}
42+
<% end %>

0 commit comments

Comments
 (0)