Skip to content

Commit

Permalink
subclass kubevirt for OSV
Browse files Browse the repository at this point in the history
  • Loading branch information
nasark committed Aug 14, 2024
1 parent 91d1f04 commit 6918d9e
Show file tree
Hide file tree
Showing 14 changed files with 275 additions and 0 deletions.
21 changes: 21 additions & 0 deletions app/models/manageiq/providers/openshift/container_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
class ManageIQ::Providers::Openshift::ContainerManager < ManageIQ::Providers::Kubernetes::ContainerManager
DEFAULT_EXTERNAL_LOGGING_ROUTE_NAME = "logging-kibana-ops".freeze

has_one :infra_manager,
:foreign_key => :parent_ems_id,
:class_name => "ManageIQ::Providers::Openshift::InfraManager",
:autosave => true,
:inverse_of => :parent_manager,
:dependent => :destroy

include ManageIQ::Providers::Openshift::ContainerManager::Options

supports :catalog
Expand All @@ -21,6 +28,20 @@ def self.event_monitor_class
ManageIQ::Providers::Openshift::ContainerManager::EventCatcher
end

def virtualization_options
[
{
:label => _('Disabled'),
:value => 'none',
},
{
:label => _('OpenShift Virtualization'),
:value => 'openshift_infra',
:pivot => 'endpoints.openshift_infra.hostname',
},
]
end

def self.raw_connect(hostname, port, options)
options[:service] ||= "openshift"
send("#{options[:service]}_connect", hostname, port, options)
Expand Down
34 changes: 34 additions & 0 deletions app/models/manageiq/providers/openshift/infra_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
ManageIQ::Providers::Kubevirt::InfraManager.include(ActsAsStiLeafClass)

class ManageIQ::Providers::OpenShift::InfraManager < ManageIQ::Providers::Kubevirt::InfraManager
belongs_to :parent_manager,
:foreign_key => :parent_ems_id,
:inverse_of => :infra_manager,
:class_name => "ManageIQ::Providers::Openshift::ContainerManager"

#
# This is the list of features that this provider supports:
#
supports :catalog
supports :provisioning

def self.ems_type
@ems_type ||= "openshift_infra".freeze
end

def self.description
@description ||= "OpenShift Virtualization".freeze
end

def self.catalog_types
{"openshift" => N_("OpenShift Virtualization")}
end

def default_authentication_type
:openshift
end

def self.display_name(number = 1)
n_('Infrastructure Provider (OpenShift Virtualization)', 'Infrastructure Providers (OpenShift Virtualization)', number)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ManageIQ::Providers::Kubevirt::InfraManager::Cluster.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Cluster < ManageIQ::Providers::Kubevirt::InfraManager::Cluster
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ManageIQ::Providers::Kubevirt::InfraManager::Connection.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Connection < ManageIQ::Providers::Kubevirt::InfraManager::Connection
end
4 changes: 4 additions & 0 deletions app/models/manageiq/providers/openshift/infra_manager/host.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ManageIQ::Providers::Kubevirt::InfraManager::Host.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Host < ManageIQ::Providers::Kubevirt::InfraManager::Host
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ManageIQ::Providers::Kubevirt::InfraManager::Provision.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Provision < ManageIQ::Providers::Kubevirt::InfraManager::Provision
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ManageIQ::Providers::Openshift::InfraManager::ProvisionWorkflow < ManageIQ::Providers::Kubevirt::InfraManager::ProvisionWorkflow
def self.provider_model
ManageIQ::Providers::Openshift::InfraManager
end

def dialog_name_from_automate(message = 'get_dialog_name')
super(message, {'platform' => 'openshift'})
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ManageIQ::Providers::Openshift::InfraManager::RefreshWorker < ManageIQ::Providers::Kubevirt::InfraManager::RefreshWorker
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
require 'concurrent/atomic/atomic_boolean'

class ManageIQ::Providers::Openshift::InfraManager::RefreshWorker::Runner < ManageIQ::Providers::Kubevirt::InfraManager::RefreshWorker::Runner

private

#
# Returns the reference to the manager.
#
# @return [ManageIQ::Providers::Kubevirt::InfraManager] The manager.
#
def manager
@manager ||= ManageIQ::Providers::Openshift::InfraManager.find(@cfg[:ems_id])
end

#
# Returns the refresh memory.
#
# @return [ManageIQ::Providers::Kubevirt::RefreshMemory] The refresh memory.
#
def memory
@memory ||= ManageIQ::Providers::Openshift::RefreshMemory.new
end

#
# Performs a full refresh.
#
def full_refresh
# Create and populate the collector, persister and parser
# and parse inventories
inventory = ManageIQ::Providers::Openshift::Inventory.build(manager, nil)
collector = inventory.collector
persister = inventory.parse

# execute persist:
persister&.persist!

# Update the memory:
memory.add_list_version(:nodes, collector.nodes.resource_version)
memory.add_list_version(:vms, collector.vms.resource_version)
memory.add_list_version(:vm_instances, collector.vm_instances.resource_version)
memory.add_list_version(:templates, collector.templates.resource_version)

manager.update(:last_refresh_error => nil, :last_refresh_date => Time.now.utc)
rescue StandardError => error
_log.error('Full refresh failed.')
_log.log_backtrace(error)
manager.update(:last_refresh_error => error.to_s, :last_refresh_date => Time.now.utc)
end

#
# Performs a partial refresh.
#
# @param notices [Array] The set of notices to process.
#
def partial_refresh(notices)
# check whether we get error about stale resource version
if notices.any? { |notice| notice.object&.kind == "Status" && notice.object&.code == 410 }
# base on the structure we do not know which watch uses stale version so we stop all
# we can't join with all the threads since we are in one
stop_watches

# clear queue
@queue.clear

# get the latest state and resource versions
full_refresh

# restart watches
start_watches
return
end

# Filter out the notices that have already been processed:
notices.reject! do |notice|
if memory.contains_notice?(notice)
_log.info(
"Notice of kind '#{notice.kind}, id '#{notice.uid}', type '#{notice.type}' and version '#{notice.resource_version}' " \
"has already been processed, will ignore it."
)
true
else
false
end
end

# The notices returned by the Kubernetes API contain always the complete representation of the object, so it isn't
# necessary to process all of them, only the last one for each object.
relevant = notices.reverse!
relevant.uniq!(&:uid)
relevant.reverse!

# Create and populate the collector:
collector = ManageIQ::Providers::Openshift::Inventory::Collector.new(manager, nil)
collector.nodes = notices_of_kind(relevant, 'Node')
collector.vms = notices_of_kind(relevant, 'VirtualMachine')
collector.vm_instances = notices_of_kind(relevant, 'VirtualMachineInstance')
collector.templates = notices_of_kind(relevant, 'VirtualMachineTemplate')

# Create the parser and persister, wire them, and execute the persist:
persister = ManageIQ::Providers::Openshift::Inventory::Persister.new(manager, nil)
parser = ManageIQ::Providers::Openshift::Inventory::Parser::PartialRefresh.new
parser.collector = collector
parser.persister = persister
parser.parse
persister.persist!

# Update the memory:
notices.each do |notice|
memory.add_notice(notice)
end

manager.update(:last_refresh_error => nil, :last_refresh_date => Time.now.utc)
rescue StandardError => error
_log.error('Partial refresh failed.')
_log.log_backtrace(error)
manager.update(:last_refresh_error => error.to_s, :last_refresh_date => Time.now.utc)
end

#
# Returns the notices that contain objects of the given kind.
#
# @param notices [Array] An array of notices.
# @param kind [String] The kind of object, for example `Node`.
# @return [Array] An array containing the notices that have the given kind.
#
def notices_of_kind(notices, kind)
notices.select { |notice| notice.kind == kind }
end

#
# Start watches
#
def start_watches
# This flag will be used to tell the threads to get out of their loops:
@finish = Concurrent::AtomicBoolean.new(false)

# Create the watches:
@watches = []
manager.with_provider_connection do |connection|
@watches << connection.watch_nodes(:resource_version => memory.get_list_version(:nodes))
@watches << connection.watch_vms(:resource_version => memory.get_list_version(:vms))
@watches << connection.watch_vm_instances(:resource_version => memory.get_list_version(:vm_instances))
@watches << connection.watch_templates(:resource_version => memory.get_list_version(:templates))
end

# Create the threads that run the watches and put the notices in the queue:
@watchers = []
@watches.each do |watch|
thread = Thread.new do
until @finish.value
watch.each do |notice|
@queue.push(notice)
end
end
end
@watchers << thread
end
end

#
# Stop all the watches
#
def stop_watches
@finish&.value = true
@watches&.each(&:finish)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ManageIQ::Providers::Openshift::InfraManager::Refresher < ManageIQ::Providers::Kubevirt::InfraManager::Refresher
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ManageIQ::Providers::Kubevirt::InfraManager::Storage.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Storage < ManageIQ::Providers::Kubevirt::InfraManager::Storage
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ManageIQ::Providers::Kubevirt::InfraManager::Template.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Template < ManageIQ::Providers::Kubevirt::InfraManager::Template
def self.display_name(number = 1)
n_('Template (OpenShift Virtualization)', 'Templates (OpenShift Virtualization)', number)
end
end
7 changes: 7 additions & 0 deletions app/models/manageiq/providers/openshift/infra_manager/vm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ManageIQ::Providers::Kubevirt::InfraManager::Vm.include(ActsAsStiLeafClass)

class ManageIQ::Providers::Openshift::InfraManager::Vm < ManageIQ::Providers::Kubevirt::InfraManager::Vm
def self.display_name(number = 1)
n_('Virtual Machine (OpenShift Virtualization)', 'Virtual Machines (OpenShift Virtualization)', number)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# This class is responsible for parsing the inventory for partial refreshes.
#
class ManageIQ::Providers::Openshift::Inventory::Parser::PartialRefresh < ManageIQ::Providers::Kubevirt::Inventory::Parser::PartialRefresh
end

0 comments on commit 6918d9e

Please sign in to comment.