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

Subclass Kubevirt InfraManager to separate Openshift Virtualization provider #264

Merged
merged 1 commit into from
Sep 10, 2024

Conversation

nasark
Copy link
Member

@nasark nasark commented Aug 7, 2024

@nasark
Copy link
Member Author

nasark commented Aug 7, 2024

@agrare WIP - need to test with an Openshift Virtualization provider and clean up specs. Feel free to review what is here though

@miq-bot miq-bot added the wip label Aug 7, 2024
@@ -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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it makes sense for this to just live in the base class, or is this intentionally overriding the class name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here because we have to override the class_name to be Openshift::InfraManager so the correct class gets created

supports :provisioning

def self.ems_type
@ems_type ||= "openshift".freeze
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has to be different than the container manager, so maybe something like openshift_virt or openshift_infra?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 openshift_infra would be good (OpenStack undercloud/InfraManager is openstack_infra)

# @return [ManageIQ::Providers::Kubevirt::InfraManager] The manager.
#
def manager
@manager ||= ManageIQ::Providers::Openshift::InfraManager.find(@cfg[:ems_id])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised so much of this overriding is necessary. Makes me wonder if there's a better way, such as providing a method like manageiq_class, which returns ManageIQ::Providers::Openshift::InfraManager, and then the actual logic would be something like

    @manager ||= manager_class.find(@cfg[:ems_id])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the simple example of course - the same comment really applies to all of the methods in this file.

@Fryguy
Copy link
Member

Fryguy commented Aug 7, 2024

Very cool! I like that we didn't need a new repository, and it's just included in the openshift repo.

@Fryguy
Copy link
Member

Fryguy commented Aug 7, 2024

One other thing I think we need is the form for adding a provider needs to change so you can only select OpenShift Virtualization under the Virtualization tab.

class ManageIQ::Providers::OpenShift::InfraManager < ManageIQ::Providers::Kubevirt::InfraManager
belongs_to :parent_manager,
:foreign_key => :parent_ems_id,
:class_name => "ManageIQ::Providers::ContainerManager"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be ManageIQ::Providers::Openshift::ContainerManager, then you can add an invere_of :infra_manager

Comment on lines 8 to 16
delegate :authentication_check,
:authentication_for_summary,
:authentication_token,
:authentications,
:endpoints,
:default_endpoint,
:zone,
:to => :parent_manager,
:allow_nil => true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of these can be inherited from the base class

end

def authentication_for_providers
authentications.where(:authtype => :openshift)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily for this PR but if most of these overrides are for :authtype => :openshift we could use e.g. a DEFAULT_AUTH_TYPE constant and switch to that in the base Kubevirt class

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g.

  def connect(opts = {}) 
    # Get the authentication token:
    token = opts[:token] || authentication_token(:kubevirt)

If we changed that to authentication_token(default_authentication_type)

#
def connect(opts = {})
# Get the authentication token:
token = opts[:token] || authentication_token(:openshift)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good example, this whole method is probably copy&paste except for this :openshift here

Comment on lines 63 to 37
def virtualization_endpoint
connection_configurations.kubevirt.try(:endpoint)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks identical to the base class

Comment on lines 4 to 10
supports :provisioning do
if ext_management_system
ext_management_system.unsupported_reason(:provisioning)
else
_('not connected to ems')
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different from the base class?

@agrare
Copy link
Member

agrare commented Aug 7, 2024

Not sure if you want to do this in another PR but we should make the "virtualization" endpoint dropdown option (https://github.com/ManageIQ/manageiq-providers-kubernetes/blob/master/app/models/manageiq/providers/kubernetes/container_manager.rb#L331-L342) in the Openshift::ContainerManager subclass only show "Openshift Virtualization"

@agrare
Copy link
Member

agrare commented Aug 8, 2024

I think we should get some VCR specs in here, kubevirt has some weird mocking that they do for their refresher specs I'm not sure I want to copy what they do but a "simple" refresher spec doing a full refresh should be sufficient.

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

def virtualization_options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def virtualization_options
def self.virtualization_options

@nasark nasark force-pushed the subclass_kubevirt branch 2 times, most recently from edce97e to 7236e7c Compare August 27, 2024 17:50
@@ -0,0 +1,2 @@
class ManageIQ::Providers::Openshift::InfraManager::RefreshWorker < ManageIQ::Providers::Kubevirt::InfraManager::RefreshWorker
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to inherit anything from the Kubevirt RefreshWorker, and doing this nests the settings under kubevirt so we typically don't do this for simple workers (e.g. see Openshift::ContainerManager::RefreshWorker it doesn't < Kubernetes)

Suggested change
class ManageIQ::Providers::Openshift::InfraManager::RefreshWorker < ManageIQ::Providers::Kubevirt::InfraManager::RefreshWorker
class ManageIQ::Providers::Openshift::InfraManager::RefreshWorker < ManageIQ::Providers::BaseManager::RefreshWorker

Copy link
Member

@agrare agrare Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to add a settings section for this new worker to config/settings.yml

diff --git a/config/settings.yml b/config/settings.yml
index dc097791..448ed39b 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -33,3 +33,4 @@
           :ems_metrics_collector_worker_openshift: {}
         :ems_refresh_worker:
           :ems_refresh_worker_openshift: {}
+          :ems_refresh_worker_openshift_infra: {}

Without this when running the full evmserverd it'll fail to start up:

adam@workstation:~/src/manageiq/manageiq$ ruby lib/workers/bin/evm_server.rb 
** ManageIQ master, codename: Spassky
/home/grare/adam/src/manageiq/manageiq/app/models/miq_worker.rb:224:in `block in fetch_worker_settings_from_options_hash': Missing config section ems_refresh_worker_openshift_infra (RuntimeError)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE we'll also need to add .service and .target files for the new openshift-infra-refresh worker in the systemd/ directory here (specs will catch this but just want to head it off now)

@agrare
Copy link
Member

agrare commented Aug 27, 2024

When running the full worker I see the following error:

[----] I, [2024-08-27T14:07:56.049629#148737:8890]  INFO -- evm: MIQ(ManageIQ::Providers::Openshift::ContainerManager::EventCatcher::Runner#start_event_monitor) EMS [api.crc.testing] as [] Starting Event Monitor Thread
[----] I, [2024-08-27T14:07:56.050809#148737:8890]  INFO -- evm: MIQ(ManageIQ::Providers::Openshift::ContainerManager::EventCatcher::Runner#start_event_monitor) EMS [api.crc.testing] as [] Started Event Monitor Thread
[----] E, [2024-08-27T14:07:56.641440#148735:8890] ERROR -- evm: MIQ(ManageIQ::Providers::Openshift::ContainerManager::RefreshWorker::Runner#refresh_block) EMS [CRC], id: [6] Refresh failed: undefined method `vms' for #<ManageIQ::Providers::Openshift::Inventory::Collector::ContainerManager
[----] E, [2024-08-27T14:07:56.642961#148735:8890] ERROR -- evm: /home/grare/adam/src/manageiq/manageiq-providers-kubevirt/app/models/manageiq/providers/kubevirt/inventory/parser/full_refresh.rb:8:in `parse'
/home/grare/adam/src/manageiq/manageiq/app/models/manageiq/providers/inventory.rb:38:in `block in parse'
/home/grare/adam/src/manageiq/manageiq/app/models/manageiq/providers/inventory.rb:35:in `each'
/home/grare/adam/src/manageiq/manageiq/app/models/manageiq/providers/inventory.rb:35:in `parse'

When using >> EmsRefresh.refresh(ManageIQ::Providers::Openshift::InfraManager.first) I see the same ManageIQ::Providers::Kubevirt::InfraManager::Host is not a subclass of ManageIQ::Providers::Openshift::InfraManager::Host (ManageIQ::Providers::BaseManager::Refresher::PartialRefreshError) that you do.

Comment on lines 39 to 40
:value => 'kubevirt',
:pivot => 'endpoints.kubevirt.hostname',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If our default_authentication_type is :openshift does this have to be endpoints.openshift.hostname ?

Copy link
Member

@agrare agrare Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we like to namespace these under the provider name e.g. https://github.com/ManageIQ/manageiq-providers-openshift/tree/master/spec/vcr_cassettes/manageiq/providers/openshift/container_manager/refresher.yml that was it is obvious what class this is for. You can use described_class.name.underscore in the VCR.use_cassette call

Copy link
Member

@agrare agrare Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer this matching the Refresher class name e.g. spec/models/manageiq/providers/openshift/container_manager/refresher_spec.rb

require 'json'
require 'recursive_open_struct'

describe ManageIQ::Providers::Openshift::Inventory::Parser::InfraManager::FullRefresh do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe ManageIQ::Providers::Openshift::Inventory::Parser::InfraManager::FullRefresh do
describe ManageIQ::Providers::Openshift::InfraManager::Refresher do

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm seem to have lost my comment, but typically we want this to match the provider class namespace like spec/vcr_cassettes/manageiq/providers/openshift/container_manager/refresher.yml
You can use VCR.use_cassette(described_class.name.underscore)

@agrare
Copy link
Member

agrare commented Aug 29, 2024

miq-bot pushed a commit to ManageIQ/manageiq-cross_repo-tests that referenced this pull request Aug 29, 2024
@nasark nasark changed the title [WIP] Subclass Kubevirt InfraManager to separate Openshift Virtualization provider Subclass Kubevirt InfraManager to separate Openshift Virtualization provider Aug 29, 2024
Copy link
Member

@Fryguy Fryguy Aug 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this live in manageiq-decorators? I prefer it in the plugin class, but wasn't sure if it was required over there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On that note, in manageiq-decorators we use symlinks when there are multiple images that point to the same thing, so this could just be a symlink over there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like it's required in manageiq-decorators

Screenshot 2024-08-30 at 12 22 38 PM

@miq-bot
Copy link
Member

miq-bot commented Sep 10, 2024

Checked commit nasark@994682d with ruby 3.1.5, rubocop 1.56.3, haml-lint 0.51.0, and yamllint
23 files checked, 0 offenses detected
Everything looks fine. ⭐

@nasark
Copy link
Member Author

nasark commented Sep 10, 2024

@nasark
Copy link
Member Author

nasark commented Sep 10, 2024

@agrare @Fryguy cross repo tests are green ManageIQ/manageiq-cross_repo-tests#911

Comment on lines +6 to +10
parser_type = if target_is_vm?(target)
"PartialTargetRefresh"
else
"FullRefresh"
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really minor for a follow-up but something this simple taking up 5 lines could be a ternary operator instead on one line

Suggested change
parser_type = if target_is_vm?(target)
"PartialTargetRefresh"
else
"FullRefresh"
end
parser_type = target_is_vm?(target) ? "PartialTargetRefresh" : "FullRefresh"

I'm not usually a "hey you can turn this big multi-step thing into one looong line" guy but this is pretty straightforward

Comment on lines +3 to +5
if !ems.kind_of?(EmsInfra)
super
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also return super unless ems.kind_of?(EmsInfra) so the entire method isn't just one if/else block.

Comment on lines +16 to +18
if !ems.kind_of?(EmsInfra)
super
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here,

Suggested change
if !ems.kind_of?(EmsInfra)
super
else
return super unless ems.kind_of?(EmsInfra)

Comment on lines +21 to +25
collector = if target_is_vm?(target)
collector_class.new(ems, target)
else
collector_class.new(ems, ems)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the same collector class I wonder if we could handle this in the initialize there, e.g. target = ems unless target.kind_of?(Vm) or something like that

end
end

it 'works correctly with one node' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a little out of place, something like "Performs a full refresh" would probably be better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On that note, a targeted refresh spec would be a good addition in the future

Copy link
Member

@agrare agrare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good some minor things that can be follow-ups

@agrare agrare merged commit 2d66f57 into ManageIQ:master Sep 10, 2024
1 of 4 checks passed
@Fryguy Fryguy added this to the Radjabov milestone Sep 10, 2024
@Fryguy Fryguy removed the wip label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Radjabov
Development

Successfully merging this pull request may close these issues.

4 participants