diff --git a/app/models/manageiq/providers/openstack/inventory/collector/target_collection.rb b/app/models/manageiq/providers/openstack/inventory/collector/target_collection.rb index ccdce70e5..7a01d86a9 100644 --- a/app/models/manageiq/providers/openstack/inventory/collector/target_collection.rb +++ b/app/models/manageiq/providers/openstack/inventory/collector/target_collection.rb @@ -225,12 +225,12 @@ def scoped_get_volume(volume_id, tenant_id) def scoped_get_snapshot(snapshot_id, tenant_id) tenant = memoized_get_tenant(tenant_id) - safe_get { @os_handle.detect_volume_service(tenant.try(:name)).snapshots.get(snapshot_id) } + safe_get { @os_handle.detect_volume_service(tenant.try(:name)).get_snapshot_details(snapshot_id).body["snapshot"] } end def scoped_get_backup(backup_id, tenant_id) tenant = memoized_get_tenant(tenant_id) - safe_get { @os_handle.detect_volume_service(tenant.try(:name)).backups.get(backup_id) } + safe_get { @os_handle.detect_volume_service(tenant.try(:name)).get_backup_details(backup_id).body["backup"] } end private diff --git a/app/models/manageiq/providers/openstack/inventory/persister/target_collection.rb b/app/models/manageiq/providers/openstack/inventory/persister/target_collection.rb index f00f628e8..a60423906 100644 --- a/app/models/manageiq/providers/openstack/inventory/persister/target_collection.rb +++ b/app/models/manageiq/providers/openstack/inventory/persister/target_collection.rb @@ -46,7 +46,8 @@ def initialize_inventory_collections add_inventory_collections_with_references( storage, %i(cloud_volumes cloud_volume_backups cloud_volume_snapshots), - :parent => manager.cinder_manager + :parent => manager.cinder_manager, + :builder_params => {:ext_management_system => manager.cinder_manager} ) ######## Custom processing of Ancestry ########## diff --git a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager.rb b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager.rb index 521bd3649..1b75f55ce 100644 --- a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager.rb +++ b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager.rb @@ -1,4 +1,9 @@ class ManageIQ::Providers::Openstack::StorageManager::CinderManager < ManageIQ::Providers::StorageManager::CinderManager + require_nested :EventCatcher require_nested :Refresher include ManageIQ::Providers::Openstack::ManagerMixin + + def self.event_monitor_class + ManageIQ::Providers::Openstack::StorageManager::CinderManager::EventCatcher + end end diff --git a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher.rb b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher.rb new file mode 100644 index 000000000..e2e3ede67 --- /dev/null +++ b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher.rb @@ -0,0 +1,20 @@ +class ManageIQ::Providers::Openstack::StorageManager::CinderManager::EventCatcher < ::MiqEventCatcher + require_nested :Runner + + def self.ems_class + ManageIQ::Providers::Openstack::StorageManager::CinderManager + end + + def self.settings_name + :event_catcher_openstack_cinder + end + + def self.all_valid_ems_in_zone + require 'manageiq/providers/openstack/legacy/openstack_event_monitor' + super.select do |ems| + ems.sync_event_monitor_available?.tap do |available| + _log.info("Event Monitor unavailable for #{ems.name}. Check log history for more details.") unless available + end + end + end +end diff --git a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher/runner.rb b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher/runner.rb new file mode 100644 index 000000000..7be4a0d64 --- /dev/null +++ b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_catcher/runner.rb @@ -0,0 +1,8 @@ +class ManageIQ::Providers::Openstack::StorageManager::CinderManager::EventCatcher::Runner < ManageIQ::Providers::BaseManager::EventCatcher::Runner + include ManageIQ::Providers::Openstack::EventCatcherMixin + + def add_openstack_queue(event) + event_hash = ManageIQ::Providers::Openstack::StorageManager::CinderManager::EventParser.event_to_hash(event, @cfg[:ems_id]) + EmsEvent.add_queue('add', @cfg[:ems_id], event_hash) + end +end diff --git a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_parser.rb b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_parser.rb new file mode 100644 index 000000000..e0320339d --- /dev/null +++ b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_parser.rb @@ -0,0 +1,39 @@ +module ManageIQ::Providers::Openstack::StorageManager::CinderManager::EventParser + def self.event_to_hash(event, ems_id) + content = message_content(event, ems_id) + event_type = content["event_type"] + payload = content["payload"] || {} + + log_header = "ems_id: [#{ems_id}] " unless ems_id.nil? + _log.debug("#{log_header}event: [#{event_type}]") if $log && $log.debug? + + # attributes that are common to all notifications + event_hash = { + :event_type => event_type, + :source => "OPENSTACK", + :message => payload, + :timestamp => content["timestamp"], + :username => content["_context_user_name"], + :full_data => event, + :ems_id => ems_id + } + + event_hash[:vm_ems_ref] = payload["instance_id"] if payload.key? "instance_id" + event_hash[:host_ems_ref] = payload["host"] if payload.key? "host" + event_hash[:availability_zone_ems_ref] = payload["availability_zone"] if payload.key? "availability_zone" + event_hash[:chain_id] = payload["reservation_id"] if payload.key? "reservation_id" + event_hash + end + + def self.message_content(event, ems_id) + unless ems_id.nil? + ems = ExtManagementSystem.find_by_id(ems_id) + if ems.connection_configuration_by_role("amqp") + if event[:content].key?("oslo.message") + return JSON.parse(event[:content]["oslo.message"]) + end + end + end + event[:content] + end +end diff --git a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_target_parser.rb b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_target_parser.rb index 6dbe83f56..b54619458 100644 --- a/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_target_parser.rb +++ b/app/models/manageiq/providers/openstack/storage_manager/cinder_manager/event_target_parser.rb @@ -21,40 +21,44 @@ def parse def parse_ems_event_targets(ems_event) target_collection = ManagerRefresh::TargetCollection.new(:manager => ems_event.ext_management_system.parent_manager, :event => ems_event) - # there's almost always a tenant id regardless of event type - collect_identity_tenant_references!(target_collection, ems_event) - if ems_event.event_type.start_with?("volume.") collect_volume_references!(target_collection, ems_event) elsif ems_event.event_type.start_with?("snapshot.") collect_snapshot_references!(target_collection, ems_event) + elsif ems_event.event_type.start_with?("backup.") + collect_backup_references!(target_collection, ems_event) end target_collection.targets end def collect_volume_references!(target_collection, ems_event) - resource_id = ems_event.full_data.fetch_path(:content, 'payload', 'volume_id') || ems_event.full_data.fetch_path(:content, 'payload', 'resource_id') - add_target(target_collection, :cloud_volumes, resource_id) if resource_id + tenant_id = ems_event.full_data.fetch_path(:content, 'payload', 'project_id') + resource_id = ems_event.full_data.fetch_path(:content, 'payload', 'resource_id') + add_target(target_collection, :cloud_volumes, resource_id, :tenant_id => tenant_id) if resource_id end def collect_snapshot_references!(target_collection, ems_event) - resource_id = ems_event.full_data.fetch_path(:content, 'payload', 'snapshot_id') || ems_event.full_data.fetch_path(:content, 'payload', 'resource_id') - add_target(target_collection, :cloud_volume_snapshots, resource_id) if resource_id + tenant_id = ems_event.full_data.fetch_path(:content, 'payload', 'project_id') + resource_id = ems_event.full_data.fetch_path(:content, 'payload', 'resource_id') + add_target(target_collection, :cloud_volume_snapshots, resource_id, :tenant_id => tenant_id) if resource_id volume_id = ems_event.full_data.fetch_path(:content, 'payload', 'volume_id') - add_target(target_collection, :cloud_volumes, volume_id) if volume_id + add_target(target_collection, :cloud_volumes, volume_id, :tenant_id => tenant_id) if volume_id end - def collect_identity_tenant_references!(target_collection, ems_event) - tenant_id = ems_event.full_data.fetch_path(:content, 'payload', 'tenant_id') || ems_event.full_data.fetch_path(:content, 'payload', 'project_id') || ems_event.full_data.fetch_path(:content, 'payload', 'initiator', 'project_id') - add_target(target_collection, :cloud_tenants, tenant_id) if tenant_id + def collect_backup_references!(target_collection, ems_event) + tenant_id = ems_event.full_data.fetch_path(:content, 'payload', 'project_id') + resource_id = ems_event.full_data.fetch_path(:content, 'payload', 'resource_id') + add_target(target_collection, :cloud_volume_backups, resource_id, :tenant_id => tenant_id) if resource_id + volume_id = ems_event.full_data.fetch_path(:content, 'payload', 'volume_id') + add_target(target_collection, :cloud_volumes, volume_id, :tenant_id => tenant_id) if volume_id end def parsed_targets(target_collection = {}) target_collection.select { |_target_class, references| references[:manager_ref].present? } end - def add_target(target_collection, association, ref) - target_collection.add_target(:association => association, :manager_ref => {:ems_ref => ref}) + def add_target(target_collection, association, ref, options = {}) + target_collection.add_target(:association => association, :manager_ref => {:ems_ref => ref}, :options => options) end end diff --git a/config/settings.yml b/config/settings.yml index 2ba3b2509..f5cedb010 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -141,7 +141,22 @@ :amqp_recovery_attempts: 4 :amqp_vhost: '/' :ceilometer: - :event_types_regex: '\A(?!firewall|floatingip|gateway|net|port|router|subnet|security_group|vpn)' + :event_types_regex: '\A(?!firewall|floatingip|gateway|net|port|router|subnet|security_group|vpn|volume|snapshot|backup)' + :event_catcher_openstack_cinder: + :poll: 15.seconds + :topics: + :nova: notifications.* + :cinder: notifications.* + :glance: notifications.* + :heat: notifications.* + :duration: 10.seconds + :capacity: 50 + :amqp_port: 5672 + :amqp_heartbeat: 30 + :amqp_recovery_attempts: 4 + :amqp_vhost: '/' + :ceilometer: + :event_types_regex: '\A(volume|snapshot|backup)' :event_catcher_openstack_infra: :poll: 15.seconds :topics: