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

Commit 52a934c

Browse files
FelisiaMpivotal-marcela-campo
authored andcommitted
v3(services) Return validation od quotas for service key creation
[#174146711](https://www.pivotaltracker.com/story/show/174146711)
1 parent ab4d27a commit 52a934c

4 files changed

Lines changed: 139 additions & 3 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module VCAP::CloudController
2+
module ServiceCredentialBindingCreateMixin
3+
private
4+
5+
def validate_service_key_quotas!(errors, validation_error_handler)
6+
quota_errors = errors.on(:quota).to_a
7+
8+
if quota_errors.include?(:service_keys_space_quota_exceeded)
9+
validation_error_handler.error!("You have exceeded your space's limit for service binding of type key.")
10+
elsif quota_errors.include?(:service_keys_quota_exceeded)
11+
validation_error_handler.error!("You have exceeded your organization's limit for service binding of type key.")
12+
end
13+
end
14+
15+
def key_validation_error!(
16+
exception,
17+
name:,
18+
validation_error_handler:
19+
)
20+
errors = exception.errors
21+
validate_service_key_quotas!(errors, validation_error_handler)
22+
23+
if errors.on([:name, :service_instance_id])&.include?(:unique)
24+
validation_error_handler.error!("The binding name is invalid. Key binding names must be unique. The service instance already has a key binding with name '#{name}'.")
25+
end
26+
27+
validation_error_handler.error!(exception.message)
28+
end
29+
end
30+
end

app/actions/service_credential_binding_key_create.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
require 'actions/mixins/service_credential_binding_validation_create'
2+
13
module VCAP::CloudController
24
module V3
35
class ServiceCredentialBindingKeyCreate
6+
include ServiceCredentialBindingCreateMixin
7+
48
class UnprocessableCreate < StandardError
59
end
610

@@ -17,8 +21,11 @@ def precursor(service_instance, name)
1721
ServiceKey.create(**binding_details)
1822
end
1923
rescue Sequel::ValidationFailed => e
20-
key_already_exists!(name) if e.message == 'name and service_instance_id unique'
21-
raise UnprocessableCreate.new(e.message)
24+
key_validation_error!(
25+
e,
26+
name: name,
27+
validation_error_handler: ValidationErrorHandler.new
28+
)
2229
end
2330

2431
private
@@ -56,6 +63,12 @@ def service_not_available!
5663
def volume_mount_not_enabled!
5764
raise UnprocessableCreate.new('Support for volume mount services is disabled.')
5865
end
66+
67+
class ValidationErrorHandler
68+
def error!(message)
69+
raise UnprocessableCreate.new(message)
70+
end
71+
end
5972
end
6073
end
6174
end

spec/request/service_credential_bindings_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,53 @@ def check_filtered_bindings(*bindings)
16591659
}))
16601660
end
16611661
end
1662+
1663+
context 'quotas restrictions' do
1664+
describe 'space quotas' do
1665+
context 'when the total service key quota has been reached' do
1666+
before do
1667+
quota = VCAP::CloudController::SpaceQuotaDefinition.make(total_service_keys: 1, organization: org)
1668+
quota.add_space(space)
1669+
1670+
VCAP::CloudController::ServiceKey.make(service_instance: service_instance)
1671+
end
1672+
1673+
it 'returns an error' do
1674+
api_call.call(space_dev_headers)
1675+
expect(last_response).to have_status_code(422)
1676+
expect(parsed_response['errors']).to include(
1677+
include({
1678+
'detail' => "You have exceeded your space's limit for service binding of type key.",
1679+
'title' => 'CF-UnprocessableEntity',
1680+
'code' => 10008,
1681+
})
1682+
)
1683+
end
1684+
end
1685+
end
1686+
1687+
describe 'organization quotas' do
1688+
context 'when the total service key quota has been reached' do
1689+
before do
1690+
quota = VCAP::CloudController::QuotaDefinition.make(total_service_keys: 1)
1691+
quota.add_organization(org)
1692+
VCAP::CloudController::ServiceKey.make(service_instance: service_instance)
1693+
end
1694+
1695+
it 'returns an error' do
1696+
api_call.call(space_dev_headers)
1697+
expect(last_response).to have_status_code(422)
1698+
expect(parsed_response['errors']).to include(
1699+
include({
1700+
'detail' => "You have exceeded your organization's limit for service binding of type key.",
1701+
'title' => 'CF-UnprocessableEntity',
1702+
'code' => 10008,
1703+
})
1704+
)
1705+
end
1706+
end
1707+
end
1708+
end
16621709
end
16631710

16641711
it 'should return 501' do

spec/unit/actions/service_credential_binding_key_create_spec.rb

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ module V3
77
RSpec.describe ServiceCredentialBindingKeyCreate do
88
subject(:action) { described_class.new }
99

10-
let(:space) { Space.make }
10+
let(:org) { Organization.make }
11+
let(:space) { Space.make(organization: org) }
1112
let(:binding_details) {}
1213
let(:name) { 'test-key' }
1314

@@ -85,10 +86,55 @@ module V3
8586
end
8687
end
8788

89+
context 'when the name is taken' do
90+
let(:existing_service_key) { ServiceKey.make(service_instance: service_instance) }
91+
92+
it 'raises an error' do
93+
expect { action.precursor(service_instance, existing_service_key.name) }.to raise_error(
94+
ServiceCredentialBindingKeyCreate::UnprocessableCreate,
95+
"The binding name is invalid. Key binding names must be unique. The service instance already has a key binding with name '#{existing_service_key.name}'."
96+
)
97+
end
98+
end
99+
88100
context 'when successful' do
89101
it_behaves_like 'the credential binding precursor'
90102
end
91103
end
104+
105+
context 'quotas' do
106+
let(:service_instance) { ManagedServiceInstance.make(space: space) }
107+
108+
context 'when service key limit has been reached for the space' do
109+
before do
110+
quota = SpaceQuotaDefinition.make(total_service_keys: 1, organization: org)
111+
quota.add_space(space)
112+
ServiceKey.make(service_instance: service_instance)
113+
end
114+
115+
it 'raises an error' do
116+
expect { action.precursor(service_instance, name) }.to raise_error(
117+
ServiceCredentialBindingKeyCreate::UnprocessableCreate,
118+
"You have exceeded your space's limit for service binding of type key."
119+
)
120+
end
121+
end
122+
123+
context 'when service key limit has been reached for the org' do
124+
before do
125+
quotas = QuotaDefinition.make(total_service_keys: 1)
126+
quotas.add_organization(org)
127+
ServiceKey.make(service_instance: service_instance)
128+
end
129+
130+
it 'raises an error' do
131+
expect { action.precursor(service_instance, name) }.to raise_error(
132+
ServiceCredentialBindingKeyCreate::UnprocessableCreate,
133+
"You have exceeded your organization's limit for service binding of type key."
134+
)
135+
end
136+
end
137+
end
92138
end
93139
end
94140
end

0 commit comments

Comments
 (0)