Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle volume snapshot status changes #439

Merged
merged 3 commits into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,27 @@ def parse_event(message)
# Aws Config Events
event["eventType"] = parse_event_type(event)
event["event_source"] = :config

elsif event.fetch_path("detail", "eventType") == "AwsApiCall"
# CloudWatch with CloudTrail for API requests Events
event["eventType"] = "AWS_API_CALL_" + event.fetch_path("detail", "eventName")
event["event_source"] = :cloud_watch_api

elsif event["detail-type"] == "EC2 Instance State-change Notification"
# CloudWatch EC2 Events
state = "_#{event.fetch_path("detail", "state")}" if event.fetch_path("detail", "state")
event["eventType"] = "#{event["detail-type"].tr(" ", "_").tr("-", "_")}#{state}"
event["event_source"] = :cloud_watch_ec2

elsif event['detail-type'] == 'EBS Snapshot Notification'
event['eventType'] = event['detail-type'].gsub(/[\s-]/, '_')
event['event_source'] = :cloud_watch_ec2_ebs_snapshot

elsif event["AlarmName"]
# CloudWatch Alarm
event["eventType"] = "AWS_ALARM_#{event["AlarmName"]}"
event["event_source"] = :cloud_watch_alarm

else
# Not recognized event, ignoring...
$log.debug("#{log_header} Parsed event from SNS Message not recognized #{event}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ def self.parse_cloud_watch_ec2_event!(event, event_hash)
event_hash[:availability_zone_ems_ref] = nil # Can't get it, needs to go through VM
end

def self.parse_cloud_watch_ec2_ebs_snapshot_event!(event, event_hash)
event_hash[:message] = event['detail']
event_hash[:timestamp] = event['time']
event_hash[:vm_ems_ref] = nil
event_hash[:availability_zone_ems_ref] = nil
end

def self.parse_cloud_watch_alarm_event!(event, event_hash)
event_hash[:message] = event["AlarmName"]
event_hash[:timestamp] = event["StateChangeTime"]
Expand All @@ -38,12 +45,13 @@ def self.event_to_hash(event, ems_id)
:ems_id => ems_id
}

unless %i(config cloud_watch_api cloud_watch_ec2 cloud_watch_alarm).include?(event["event_source"])
parse_method_name = "parse_#{event["event_source"]}_event!"
if singleton_class.method_defined?(parse_method_name)
send(parse_method_name, event, event_hash)
else
raise "Unsupported event source #{event["event_source"]}"
end

send("parse_#{event["event_source"]}_event!", event, event_hash)

log_header = "ems_id: [#{ems_id}] " unless ems_id.nil?
_log.debug("#{log_header}event: [#{event[:message]}]")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def parse_ems_event_targets(event)
event.full_data.fetch_path("detail", "responseElements") || {})
when :cloud_watch_ec2
collect_cloudwatch_ec2_references!(target_collection, event.full_data)
when :cloud_watch_ec2_ebs_snapshot
collect_cloudwatch_ec2_ebs_snapshot_references!(target_collection, event.full_data)
when :config
collect_config_references!(target_collection, event.full_data)
end
Expand All @@ -54,6 +56,12 @@ def collect_cloudwatch_ec2_references!(target_collection, event_data)
add_target(target_collection, :vms, instance_id) if instance_id
end

def collect_cloudwatch_ec2_ebs_snapshot_references!(target_collection, event_data)
if (snapshot_id = event_data.fetch_path('detail', 'snapshot_id'))
add_target(target_collection, :cloud_volume_snapshots, snapshot_id.split('/').last)
end
end

def collect_config_references!(target_collection, event_data)
resource_type = event_data.fetch_path("configurationItem", "resourceType")
resource_id = event_data.fetch_path("configurationItem", "resourceId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ def self.create_snapshot(cloud_volume, options = {})

def raw_delete_snapshot
with_provider_object(&:delete)
update!(:status => 'deleting')
EmsRefresh.queue_refresh(
ManagerRefresh::Target.new(
:association => :cloud_volume_snapshots,
:manager_ref => { :ems_ref => ems_ref },
:manager_id => ems_id,
)
)
rescue => e
_log.error "volume=[#{name}], error: #{e}"
raise MiqException::MiqVolumeSnapshotDeleteError, e.to_s, e.backtrace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Type" : "Notification",
"MessageId" : "38a41df6-c96f-52fe-86b5-4e93f8ca43e1",
"TopicArn" : "arn:aws:sns:eu-central-1:200278856672:AWSConfig_topic",
"Message" : "{\"version\":\"0\",\"id\":\"29df4485-86c1-db72-78d1-e0ecdbdd3021\",\"detail-type\":\"EBS Snapshot Notification\",\"source\":\"aws.ec2\",\"account\":\"200278856672\",\"time\":\"2018-05-03T15:48:52Z\",\"region\":\"eu-central-1\",\"resources\":[\"arn:aws:ec2::eu-central-1:snapshot/snap-0089df02c4373d7a0\"],\"detail\":{\"event\":\"createSnapshot\",\"result\":\"succeeded\",\"cause\":\"\",\"request-id\":\"\",\"snapshot_id\":\"arn:aws:ec2::eu-central-1:snapshot/snap-0089df02c4373d7a0\",\"source\":\"arn:aws:ec2::eu-central-1:volume/vol-006e52cf74d8f3e7c\",\"startTime\":\"2018-05-03T15:48:26.000Z\",\"endTime\":\"2018-05-03T15:48:52.883Z\"}}",
"Timestamp" : "2018-05-03T15:48:53.716Z",
"SignatureVersion" : "1",
"Signature" : "A1pihqCuih3CEAqzej6OZLjUQw3UVjmvucSKZu90Rqak/pKH1gbiLOzz5hEEm6scFt/RAhSZ/tQpjs5tWyKylDWgawUFr9KZlir5uqZnjAA/8PVdtSG4h7Rz6mM6T9aZliXDdx/NfrOX6rgDM6PomzqDkAAM1M2bQkq6wLRr+OUjKjutJP0otLNwl834QHRNOf9SCdBuCK7I6Rr0LtS304jo/grcodc8DROMfunihjSItbamtEudSSS1DlcQBbcc/me7r1u3nzLHxFXyijUxTr4lqPqPE7Do51/TMcT9QzVyMyl3TNfemR+7cwiPPa4fdmaxZ8ySVkn9s/1nVhsIBg==",
"SigningCertURL" : "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
"UnsubscribeURL" : "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-central-1:200278856672:AWSConfig_topic:fb3aae8a-78bd-45c2-aeb7-75097bd230d9"
}
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,15 @@
)
)
end

it 'parses EBS_Snapshot_Notification event' do
ems_event = create_ems_event("config/EBS_Snapshot_Notification.json")
parsed_targets = described_class.new(ems_event).parse

expect(parsed_targets.size).to eq(1)
expect(target_references(parsed_targets))
.to match_array([[:cloud_volume_snapshots, { :ems_ref => 'snap-0089df02c4373d7a0' }]])
end
end

context "AWS CloudWatch with CloudTrail API" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
describe "cloud volume operations" do
context "#delete_snapshot" do
it "deletes the cloud volume snapshot" do
stubbed_responses = {
:ec2 => {
:delete_snapshot => {}
}
}
stubbed_responses = { :ec2 => { :delete_snapshot => {} } }
allow(EmsRefresh).to receive(:queue_refresh)

with_aws_stubbed(stubbed_responses) do
expect(cloud_volume_snapshot.delete_snapshot).to be_truthy
expect { cloud_volume_snapshot.delete_snapshot }.to_not raise_error
expect(cloud_volume_snapshot.status).to eq('deleting')
expect(EmsRefresh).to have_received(:queue_refresh)
end
end

Expand Down