1
+ require 'oj'
2
+
1
3
module VCAP ::CloudController
2
4
class SyslogDrainUrlsInternalController < RestController ::BaseController
3
5
# Endpoint uses mutual tls for auth, handled by nginx
@@ -55,32 +57,35 @@ def listv5
55
57
join ( :apps , guid : :app_guid ) .
56
58
join ( :spaces , guid : :apps__space_guid ) .
57
59
join ( :organizations , id : :spaces__organization_id ) .
60
+ join ( :service_instances , guid : :service_bindings__service_instance_guid ) .
58
61
select (
59
62
:service_bindings__syslog_drain_url ,
60
63
:service_bindings__credentials ,
61
64
:service_bindings__salt ,
62
65
:service_bindings__encryption_key_label ,
63
66
:service_bindings__encryption_iterations ,
64
67
:service_bindings__app_guid ,
68
+ :service_bindings__service_instance_guid ,
65
69
:apps__name___app_name ,
66
70
:spaces__name___space_name ,
67
- :organizations__name___organization_name
71
+ :organizations__name___organization_name ,
72
+ :service_instances__is_gateway_service___is_managed_service
68
73
) .
69
74
where ( service_bindings__syslog_drain_url : syslog_drain_urls_query ) .
70
75
71
76
each_with_object ( { } ) do |item , injected |
72
77
syslog_drain_url = item [ :syslog_drain_url ]
73
- credentials = item . credentials
74
- cert = credentials &.fetch ( 'cert' , '' ) || ''
75
- key = credentials &.fetch ( 'key' , '' ) || ''
76
- ca = credentials &.fetch ( 'ca' , '' ) || ''
78
+
77
79
hostname = hostname_from_app_name ( item [ :organization_name ] , item [ :space_name ] , item [ :app_name ] )
78
80
app_guid = item [ :app_guid ]
79
81
82
+ cert , key , ca = fetch_credentials_from_cache ( item )
83
+
80
84
injected_item = injected [ syslog_drain_url ] ||= {
81
85
url : syslog_drain_url ,
82
86
binding_data_map : { }
83
87
}
88
+
84
89
cert_item = injected_item [ :binding_data_map ] [ [ key , cert , ca ] ] ||= {
85
90
cert : cert ,
86
91
key : key ,
@@ -99,11 +104,45 @@ def listv5
99
104
100
105
next_page_token = nil
101
106
next_page_token = last_id + batch_size unless bindings . empty?
102
- [ HTTP ::OK , MultiJson . dump ( { results : bindings , next_id : next_page_token } , pretty : true ) ]
107
+ [ HTTP ::OK , Oj . dump ( { results : bindings , next_id : next_page_token } ) ]
103
108
end
104
109
105
110
private
106
111
112
+ def upsi_service_instance_credential_cache
113
+ @upsi_service_instance_credential_cache ||= { }
114
+ end
115
+
116
+ # Service Binding credentials are stored as encrypted values in CCDB.
117
+ # Decrypting them is computationally expensive and has caused performance
118
+ # issues since this endpoint may decrypt credentials from thousands of service bindings.
119
+ #
120
+ # Since all user-provided service instance bindings share the same credentials
121
+ # as their service instance we can safely cache the for a given service instance guid.
122
+ def fetch_credentials_from_cache ( item )
123
+ if item [ :is_managed_service ]
124
+ credentials = item . credentials
125
+ cert = credentials &.fetch ( 'cert' , '' ) || ''
126
+ key = credentials &.fetch ( 'key' , '' ) || ''
127
+ ca = credentials &.fetch ( 'ca' , '' ) || ''
128
+ else # service is user-provided
129
+ upsi_service_instance_credential_cache [ item . service_instance_guid ] ||= { }
130
+
131
+ if upsi_service_instance_credential_cache [ item . service_instance_guid ] . empty?
132
+ credentials = item . credentials
133
+ upsi_service_instance_credential_cache [ item . service_instance_guid ] [ 'cert' ] = credentials &.fetch ( 'cert' , '' ) || ''
134
+ upsi_service_instance_credential_cache [ item . service_instance_guid ] [ 'key' ] = credentials &.fetch ( 'key' , '' ) || ''
135
+ upsi_service_instance_credential_cache [ item . service_instance_guid ] [ 'ca' ] = credentials &.fetch ( 'ca' , '' ) || ''
136
+ end
137
+
138
+ cert = upsi_service_instance_credential_cache [ item . service_instance_guid ] . fetch ( 'cert' , '' )
139
+ key = upsi_service_instance_credential_cache [ item . service_instance_guid ] . fetch ( 'key' , '' )
140
+ ca = upsi_service_instance_credential_cache [ item . service_instance_guid ] . fetch ( 'ca' , '' )
141
+ end
142
+
143
+ [ cert , key , ca ]
144
+ end
145
+
107
146
def syslog_drain_urls_query
108
147
ServiceBinding .
109
148
distinct .
0 commit comments