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

Commit fc537f9

Browse files
author
Derik Evangelista
committed
v3: audit events for managed service instance
[#171629626](https://www.pivotaltracker.com/story/show/171629626)
1 parent 8afe080 commit fc537f9

7 files changed

Lines changed: 88 additions & 35 deletions

File tree

app/actions/service_instance_create_managed.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ def create(message)
3838

3939
service_event_repository.record_service_instance_event(:start_create, instance, message.audit_hash)
4040

41-
creation_job = V3::CreateServiceInstanceJob.new(instance.guid, arbitrary_parameters: message.parameters)
41+
creation_job = V3::CreateServiceInstanceJob.new(
42+
instance.guid,
43+
arbitrary_parameters: message.parameters,
44+
user_audit_info: service_event_repository.user_audit_info
45+
)
4246
pollable_job = Jobs::Enqueuer.new(creation_job, queue: Jobs::Queues.generic).enqueue_pollable
4347
end
4448

app/controllers/v3/service_instances_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ def create_user_provided(message)
181181
end
182182

183183
def create_managed(message, space:)
184-
service_event_repository = VCAP::CloudController::Repositories::ServiceEventRepository::WithUserActor.new(user_audit_info)
184+
service_event_repository = VCAP::CloudController::Repositories::ServiceEventRepository.new(user_audit_info)
185185
service_plan = ServicePlan.first(guid: message.service_plan_guid)
186186
unprocessable_service_plan! unless service_plan &&
187187
visible_to_current_user?(plan: service_plan) &&

app/jobs/v3/services/create_service_instance_job.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
module VCAP::CloudController
44
module V3
55
class CreateServiceInstanceJob < VCAP::CloudController::Jobs::CCJob
6-
def initialize(service_instance_guid, arbitrary_parameters: {})
6+
def initialize(service_instance_guid, arbitrary_parameters: {}, user_audit_info:)
77
@service_instance_guid = service_instance_guid
88
@arbitrary_parameters = arbitrary_parameters
9+
@user_audit_info = user_audit_info
910
end
1011

1112
def perform
@@ -36,7 +37,8 @@ def success(job)
3637
polling_job = VCAP::CloudController::V3::FetchLastOperationJob.new(
3738
service_instance_guid: service_instance.guid,
3839
pollable_job_guid: pollable_job.guid,
39-
request_attrs: @arbitrary_parameters
40+
request_attrs: @arbitrary_parameters,
41+
user_audit_info: @user_audit_info,
4042
)
4143
enqueuer = Jobs::Enqueuer.new(polling_job, queue: Jobs::Queues.generic)
4244
delayed_job = enqueuer.enqueue
@@ -47,6 +49,7 @@ def success(job)
4749
)
4850
else
4951
pollable_job.update(state: PollableJobModel::COMPLETE_STATE)
52+
record_event(service_instance, @arbitrary_parameters)
5053
end
5154
end
5255

@@ -72,6 +75,14 @@ def display_name
7275

7376
private
7477

78+
def repository
79+
Repositories::ServiceEventRepository.new(@user_audit_info)
80+
end
81+
82+
def record_event(service_instance, request_attrs)
83+
repository.record_service_instance_event(:create, service_instance, request_attrs)
84+
end
85+
7586
def service_instance
7687
@service_instance ||= ManagedServiceInstance.first(guid: service_instance_guid)
7788
end

app/jobs/v3/services/fetch_last_operation_job.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ class FetchLastOperationJob < VCAP::CloudController::Jobs::CCJob
88

99
attr_accessor :service_instance_guid, :request_attrs, :poll_interval, :end_timestamp
1010

11-
def initialize(service_instance_guid:, request_attrs:, end_timestamp: nil, pollable_job_guid:)
11+
def initialize(service_instance_guid:, request_attrs:, end_timestamp: nil, pollable_job_guid:, user_audit_info:)
1212
@service_instance_guid = service_instance_guid
1313
@request_attrs = request_attrs
1414
@end_timestamp = end_timestamp || new_end_timestamp
1515
@pollable_job_guid = pollable_job_guid
16+
@user_audit_info = user_audit_info
1617
update_polling_interval
1718
end
1819

@@ -74,6 +75,10 @@ def operation_failed!(msg)
7475
raise CloudController::Errors::ApiError.new_from_details('ServiceInstanceProvisionFailed', msg)
7576
end
7677

78+
def repository
79+
Repositories::ServiceEventRepository.new(@user_audit_info)
80+
end
81+
7782
def pollable_job
7883
PollableJobModel.where(guid: @pollable_job_guid)
7984
end
@@ -86,6 +91,11 @@ def try_again
8691
)
8792
end
8893

94+
def record_event(service_instance, request_attrs)
95+
type = service_instance.last_operation.type
96+
repository.record_service_instance_event(type, service_instance, request_attrs)
97+
end
98+
8999
def update_with_attributes(last_operation, service_instance, intended_operation)
90100
ServiceInstance.db.transaction do
91101
service_instance.lock!
@@ -97,6 +107,7 @@ def update_with_attributes(last_operation, service_instance, intended_operation)
97107

98108
if service_instance.last_operation.state == 'succeeded'
99109
apply_proposed_changes(service_instance)
110+
record_event(service_instance, @request_attrs)
100111
end
101112
end
102113
end

spec/request/service_instances_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ def check_filtered_instances(*instances)
768768
labels: { baz: 'qux' },
769769
annotations: { foo: 'bar' }
770770
)
771-
)
771+
)
772772
end
773773

774774
it 'creates a service instance in the database' do

spec/unit/jobs/v3/create_service_instance_job_spec.rb

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,26 @@ module V3
3737
service_instance.service_instance_operation = operation
3838
service_instance
3939
end
40+
41+
let(:user) { User.make }
42+
let(:user_email) { 'foo@example.com' }
43+
let(:user_audit_info) { UserAuditInfo.new(user_guid: user.guid, user_email: user_email) }
44+
let(:request_attr) {
45+
{
46+
dummy_data: 'dummy_data'
47+
}
48+
}
4049
let(:job) do
4150
CreateServiceInstanceJob.new(
4251
service_instance.guid,
43-
{}
52+
arbitrary_parameters: request_attr,
53+
user_audit_info: user_audit_info,
4454
)
4555
end
4656

47-
def run_job(job, jobs_succeeded: 2, jobs_failed: 0)
57+
def run_job(job, jobs_succeeded: 2, jobs_failed: 0, jobs_to_execute: 100)
4858
pollable_job = Jobs::Enqueuer.new(job, { queue: Jobs::Queues.generic, run_at: Delayed::Job.db_time_now }).enqueue_pollable
49-
execute_all_jobs(expected_successes: jobs_succeeded, expected_failures: jobs_failed)
59+
execute_all_jobs(expected_successes: jobs_succeeded, expected_failures: jobs_failed, jobs_to_execute: jobs_to_execute)
5060
pollable_job
5161
end
5262

@@ -95,6 +105,12 @@ def run_job(job, jobs_succeeded: 2, jobs_failed: 0)
95105
expect(service_instance.last_operation.type).to eq('create')
96106
expect(service_instance.last_operation.state).to eq('in progress')
97107
end
108+
109+
it 'does not create an audit event`' do
110+
run_job(job, jobs_succeeded: 1, jobs_to_execute: 1)
111+
112+
expect(Event.find(type: 'audit.service_instance.create')).to be_nil
113+
end
98114
end
99115

100116
context 'when broker returns `succeeded` on the provision request' do
@@ -132,6 +148,15 @@ def run_job(job, jobs_succeeded: 2, jobs_failed: 0)
132148
expect(service_instance.last_operation.type).to eq('create')
133149
expect(service_instance.last_operation.state).to eq('succeeded')
134150
end
151+
152+
it 'creates an audit event' do
153+
run_job(job, jobs_succeeded: 1)
154+
155+
event = Event.find(type: 'audit.service_instance.create')
156+
expect(event).to be
157+
expect(event.actee).to eq(service_instance.guid)
158+
expect(event.metadata['request']).to have_key('dummy_data')
159+
end
135160
end
136161

137162
context 'when the broker client raises during provision' do

spec/unit/jobs/v3/services/fetch_last_operation_job_spec.rb

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module V3
2727

2828
let(:user) { User.make }
2929
let(:user_email) { 'fake@mail.foo' }
30+
let(:user_audit_info) { UserAuditInfo.new(user_guid: user.guid, user_email: user_email) }
3031

3132
let(:status) { 200 }
3233
let(:state) { 'succeeded' }
@@ -60,6 +61,7 @@ module V3
6061
service_instance_guid: service_instance.guid,
6162
request_attrs: request_attrs,
6263
pollable_job_guid: pollable_job_guid,
64+
user_audit_info: user_audit_info,
6365
)
6466
end
6567

@@ -204,6 +206,32 @@ def run_job(job, successes: 1, failures: 0)
204206

205207
expect(pollable_job.reload.state).to eq(PollableJobModel::COMPLETE_STATE)
206208
end
209+
210+
context 'audit events' do
211+
context 'when user information is provided' do
212+
it 'should create audit event' do
213+
run_job(job)
214+
215+
event = Event.find(type: 'audit.service_instance.create')
216+
expect(event).to be
217+
expect(event.actee).to eq(service_instance.guid)
218+
expect(event.metadata['request']).to have_key('dummy_data')
219+
end
220+
end
221+
222+
context 'when the user has gone away' do
223+
it 'should create an audit event' do
224+
user.destroy
225+
226+
run_job(job)
227+
228+
event = Event.find(type: 'audit.service_instance.create')
229+
expect(event).to be
230+
expect(event.actee).to eq(service_instance.guid)
231+
expect(event.metadata['request']).to have_key('dummy_data')
232+
end
233+
end
234+
end
207235
end
208236

209237
context 'when the broker responds with state `in progress`' do
@@ -506,32 +534,6 @@ def run_job(job, successes: 1, failures: 0)
506534
expect(event).to be
507535
end
508536
end
509-
510-
context 'when user information is provided' do
511-
context 'and the last operation type is create' do
512-
it 'should create audit event' do
513-
run_job(job)
514-
515-
event = Event.find(type: 'audit.service_instance.create')
516-
expect(event).to be
517-
expect(event.actee).to eq(service_instance.guid)
518-
expect(event.metadata['request']).to have_key('dummy_data')
519-
end
520-
end
521-
end
522-
523-
context 'when the user has gone away' do
524-
it 'should create an audit event' do
525-
user.destroy
526-
527-
run_job(job)
528-
529-
event = Event.find(type: 'audit.service_instance.create')
530-
expect(event).to be
531-
expect(event.actee).to eq(service_instance.guid)
532-
expect(event.metadata['request']).to have_key('dummy_data')
533-
end
534-
end
535537
end
536538

537539
context 'when the poll_interval is changed after the job was created' do

0 commit comments

Comments
 (0)