Skip to content

Commit d27d352

Browse files
authored
Orphan mitigation for instances/bindings in state "create failed" (#3988)
* Orphan mitigation for instances/bindings in state "create failed" It might be that a service brokr that responds with create failed on a service instance/binding creation keeps some meta data about the resource. The OSBAPI spec recommends that the platform performs orphan mitigation in such a case. Adding orphan mitigation to instance and binding creations, if they are in state create failed.
1 parent 14d72af commit d27d352

8 files changed

+37
-4
lines changed

app/actions/service_credential_binding_app_create.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ def precursor(service_instance, message:, app: nil, volume_mount_services_enable
3232

3333
ServiceBinding.new.tap do |b|
3434
ServiceBinding.db.transaction do
35-
binding.destroy if binding
35+
if binding
36+
binding.destroy
37+
VCAP::Services::ServiceBrokers::V2::OrphanMitigator.new.cleanup_failed_bind(binding)
38+
end
3639
b.save_with_attributes_and_new_operation(
3740
binding_details,
3841
CREATE_INITIAL_OPERATION

app/actions/service_credential_binding_key_create.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ def precursor(service_instance, message:)
2727

2828
ServiceKey.new.tap do |b|
2929
ServiceKey.db.transaction do
30-
key.destroy if key
30+
if key
31+
key.destroy
32+
VCAP::Services::ServiceBrokers::V2::OrphanMitigator.new.cleanup_failed_bind(key)
33+
end
3134
b.save_with_attributes_and_new_operation(
3235
binding_details,
3336
CREATE_INITIAL_OPERATION

app/actions/service_route_binding_create.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ def precursor(service_instance, route, message:)
2626

2727
RouteBinding.new.tap do |b|
2828
RouteBinding.db.transaction do
29-
binding.destroy if binding
29+
if binding
30+
binding.destroy
31+
VCAP::Services::ServiceBrokers::V2::OrphanMitigator.new.cleanup_failed_bind(binding)
32+
end
3033
b.save_with_attributes_and_new_operation(
3134
binding_details,
3235
CREATE_INITIAL_OPERATION

app/actions/v3/service_instance_create_managed.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'services/service_brokers/service_client_provider'
2+
require 'services/service_brokers/v2/orphan_mitigator'
23
require 'actions/mixins/service_instance_create'
34
require 'actions/metadata_update'
45

@@ -39,7 +40,10 @@ def precursor(message:, service_plan:)
3940

4041
ManagedServiceInstance.new.tap do |i|
4142
ManagedServiceInstance.db.transaction do
42-
instance.destroy if instance&.create_failed?
43+
if instance&.create_failed?
44+
instance.destroy
45+
VCAP::Services::ServiceBrokers::V2::OrphanMitigator.new.cleanup_failed_provision(instance)
46+
end
4347
i.save_with_new_operation(attr, last_operation)
4448
MetadataUpdate.update(i, message)
4549
end

spec/unit/actions/service_credential_binding_app_create_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,12 @@ module V3
7979
end
8080

8181
context "when the last binding operation is in 'create failed' state" do
82+
let(:fake_orphan_mitigator) { instance_double(VCAP::Services::ServiceBrokers::V2::OrphanMitigator) }
83+
8284
before do
8385
binding.save_with_attributes_and_new_operation({}, { type: 'create', state: 'failed' })
86+
allow(VCAP::Services::ServiceBrokers::V2::OrphanMitigator).to receive(:new).and_return(fake_orphan_mitigator)
87+
allow(fake_orphan_mitigator).to receive(:cleanup_failed_bind).with(binding)
8488
end
8589

8690
it 'deletes the existing binding and creates a new one' do
@@ -89,6 +93,7 @@ module V3
8993
expect(b.guid).not_to eq(binding.guid)
9094
expect(b).to be_create_in_progress
9195
expect { binding.reload }.to raise_error Sequel::NoExistingObject
96+
expect(fake_orphan_mitigator).to have_received(:cleanup_failed_bind).with(binding)
9297
end
9398
end
9499

spec/unit/actions/service_credential_binding_key_create_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ module V3
6767
end
6868

6969
context "when the last key operation is in 'create failed' state" do
70+
let(:fake_orphan_mitigator) { instance_double(VCAP::Services::ServiceBrokers::V2::OrphanMitigator) }
71+
7072
before do
7173
binding.save_with_attributes_and_new_operation({}, { type: 'create', state: 'failed' })
74+
allow(VCAP::Services::ServiceBrokers::V2::OrphanMitigator).to receive(:new).and_return(fake_orphan_mitigator)
75+
allow(fake_orphan_mitigator).to receive(:cleanup_failed_bind).with(binding)
7276
end
7377

7478
it 'deletes the existing key and creates a new one' do
@@ -77,6 +81,7 @@ module V3
7781
expect(b.guid).not_to eq(binding.guid)
7882
expect(b).to be_create_in_progress
7983
expect { binding.reload }.to raise_error Sequel::NoExistingObject
84+
expect(fake_orphan_mitigator).to have_received(:cleanup_failed_bind).with(binding)
8085
end
8186
end
8287

spec/unit/actions/service_route_binding_create_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,12 @@ module V3
119119
end
120120

121121
context "when the last service route binding operation is in 'create failed' state" do
122+
let(:fake_orphan_mitigator) { instance_double(VCAP::Services::ServiceBrokers::V2::OrphanMitigator) }
123+
122124
before do
123125
binding.save_with_attributes_and_new_operation({}, { type: 'create', state: 'failed' })
126+
allow(VCAP::Services::ServiceBrokers::V2::OrphanMitigator).to receive(:new).and_return(fake_orphan_mitigator)
127+
allow(fake_orphan_mitigator).to receive(:cleanup_failed_bind).with(binding)
124128
end
125129

126130
it 'deletes the existing binding and creates a new one' do
@@ -129,6 +133,7 @@ module V3
129133
expect(b.guid).not_to eq(binding.guid)
130134
expect(b).to be_create_in_progress
131135
expect { binding.reload }.to raise_error Sequel::NoExistingObject
136+
expect(fake_orphan_mitigator).to have_received(:cleanup_failed_bind).with(binding)
132137
end
133138
end
134139

spec/unit/actions/v3/service_instance_create_managed_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,19 @@ module V3
123123
end
124124

125125
context "when the last operation is in state 'create failed'" do
126+
let(:fake_orphan_mitigator) { instance_double(VCAP::Services::ServiceBrokers::V2::OrphanMitigator) }
127+
126128
before do
127129
instance.save_with_new_operation({}, { type: 'create', state: 'failed' })
130+
allow(VCAP::Services::ServiceBrokers::V2::OrphanMitigator).to receive(:new).and_return(fake_orphan_mitigator)
131+
allow(fake_orphan_mitigator).to receive(:cleanup_failed_provision).with(instance)
128132
end
129133

130134
it 'deletes the existing service instance and creates a new one' do
131135
service_instance = action.precursor(message:, service_plan:)
132136

133137
expect(service_instance.guid).not_to eq(instance.guid)
138+
expect(fake_orphan_mitigator).to have_received(:cleanup_failed_provision).with(instance)
134139
expect(service_instance.last_operation.type).to eq('create')
135140
expect(service_instance.last_operation.state).to eq('initial')
136141
end

0 commit comments

Comments
 (0)