Repository: ManageIQ/manageiq-providers-kubevirt
Pull request #276: Replace fog-kubevirt with kubevirt-sdk-ruby
Author: login: agrare
Labels: name: enhancement
Created: 2025-02-18T19:33:03Z | Merged: 2025-03-06T16:33:18Z

Alternative to https://github.com/ManageIQ/manageiq-providers-kubevirt/pull/265
This uses an openapi generated client gem (https://github.com/ManageIQ/kubevirt-sdk-ruby/) based on https://github.com/kubevirt/kubevirt/tree/main/api/openapi-spec

Because the kubevirt API doesn't follow the same rules as most of the rest of the k8s API, kubeclient isn't able to generate methods for all endpoints.  This is also true of the `oc` utility which is why there is a `virtctl` cli (https://kubevirt.io/user-guide/user_workloads/virtctl_client_tool/)

Dependents:
* https://github.com/ManageIQ/manageiq-providers-openshift/pull/276

<!--
1. Describe what this Pull Request does and why you think it is needed.
   If this PR includes UI or CLI changes, please include Before/After screenshots
   If this PR includes performance changes, please include Before/After metrics showing improvement.
-->

<!--
2. If this fixes an existing issue, please specify in `Fixes #<id>` format
   (As described in https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue)
-->

<!--
3. Ask @miq-bot to apply a scope label (bug, enhancement, etc) and any additional reviewers or assignees.
   (As described in https://github.com/ManageIQ/miq_bot#requested-tasks)
   e.g. `@miq-bot add-label label_name`
        `@miq-bot add-reviewer @name`
-->



Diff:
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager.rb b/app/models/manageiq/providers/kubevirt/infra_manager.rb
index d05305c1..38cc4cb0 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager.rb
@@ -108,8 +108,18 @@ def self.params_for_create
   end
 
   def self.verify_credentials(args)
-    kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token")&.symbolize_keys)
-    kubevirt&.valid? && kubevirt&.virt_supported?
+    kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token", "security_protocol", "certificate_authority")&.symbolize_keys)
+    kubevirt&.get_api_group_list
+    kubevirt&.get_api_group_kubevirt_io
+  rescue Kubevirt::ApiError => err
+    case err.code
+    when 404
+      raise MiqException::Error, N_("%{product_name} API Group Not found") % {:product_name => product_name}
+    when 0
+      raise MiqException::MiqUnreachableError, err.message
+    else
+      raise
+    end
   end
 
   #
@@ -122,13 +132,21 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = opts[:security_protocol] != "ssl-without-validation"
+    kubevirt_api_client.config.cert_file  = opts[:certificate_authority]
+    kubevirt_api_client.config.logger     = $kubevirt_log
+    kubevirt_api_client.config.debugging  = Settings.log.level == "debug"
+    kubevirt_api_client.default_headers["Authorization"] = "Bearer #{api_key}"
+
+    Kubevirt::DefaultApi.new(kubevirt_api_client)
   end
 
   #
@@ -150,7 +168,17 @@ def has_credentials?(_type = nil)
   # @param opts [Hash] Additional options to control how to perform the verification.
   #
   def verify_credentials(_type = nil, opts = {})
-    with_provider_connection(opts, &:valid?)
+    with_provider_connection(opts) do |kubevirt|
+      # First check that we're able to connect to the k8s API
+      kubevirt.get_api_group_list
+      # Then check that we can access the /apis/kubevirt.io API group
+      kubevirt.get_api_group_kubevirt_io
+    rescue Kubevirt::ApiError => err
+      raise MiqException::MiqInvalidCredentialsError, N_("Unauthorized") if err.code == 401
+      raise MiqException::MiqUnreachableError,        N_("Unreachable")  if err.code == 0
+      raise MiqException::MiqUnreachableError,        N_("Virtualization not enabled") if err.code == 404
+      raise
+    end
   end
 
   #
@@ -159,11 +187,7 @@ def verify_credentials(_type = nil, opts = {})
   #
   # @param opts [Hash] Additional options to control how to perform the verification.
   #
-  def verify_virt_supported(opts)
-    virt_supported = with_provider_connection(opts, &:virt_supported?)
-    raise "Kubevirt deployment was not found on provider" unless virt_supported
-    virt_supported
-  end
+  alias verify_virt_supported verify_credentials
 
   def authentication_status(type = default_authentication_type)
     authentication_best_fit(type).try(:status)
@@ -186,16 +210,27 @@ def connect(opts = {})
     # Get the authentication token:
     token = opts[:token] || authentication_token(default_authentication_type)
 
-    # Create and return the connection:
-    endpoint = default_endpoint
-    self.class::Connection.new(
-      :host      => endpoint.hostname,
-      :port      => endpoint.port,
-      :token     => token,
-      :namespace => opts[:namespace] || ""
+    self.class.raw_connect(
+      :server                => default_endpoint.hostname,
+      :port                  => default_endpoint.port,
+      :security_protocol     => default_endpoint.security_protocol,
+      :certificate_authority => default_endpoint.certificate_authority,
+      :token                 => token
     )
   end
 
+  def kubeclient(api_group = nil)
+    api_path, api_version = api_group&.split("/")
+
+    options = {:service => "kubernetes"}
+    if api_path
+      options[:path] = "/apis/#{api_path}"
+      options[:version] = api_version
+    end
+
+    parent_manager.connect(options)
+  end
+
   def virtualization_endpoint
     connection_configurations.kubevirt.try(:endpoint)
   end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/connection.rb b/app/models/manageiq/providers/kubevirt/infra_manager/connection.rb
deleted file mode 100644
index 38e476de..00000000
--- a/app/models/manageiq/providers/kubevirt/infra_manager/connection.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# This class hides the fact that when connecting to KubeVirt we need to use different API servers:
-# one for the standard Kubernetes API and another one for the KubeVirt API.
-#
-class ManageIQ::Providers::Kubevirt::InfraManager::Connection
-  #
-  # Creates a new connection with the given options. Note that the actual connection to the
-  # Kubernetes API is created lazily, when needed, so the fact that this method succeeds does *not*
-  # indicate that the connection parameters are correct.
-  #
-  # @param opts [Hash] The options used to create the connection.
-  #
-  # @option opts [String] :host The name of the host of the Kubernetes API server.
-  # @option opts [Integer] :port The port number of the Kubernetes API server.
-  # @option opts [String] :token The authentication token.
-  #
-  def initialize(opts = {})
-    require 'fog/kubevirt'
-    # create fog based connection
-    @conn = Fog::Kubevirt::Compute.new(
-      :kubevirt_hostname  => opts[:host],
-      :kubevirt_port      => opts[:port],
-      :kubevirt_token     => opts[:token],
-      :kubevirt_namespace => opts[:namespace] || 'default',
-      :kubevirt_log       => $kubevirt_log
-    )
-
-    # Nothing else is done here, as this method should never throw an exception, even if the
-    # credentials are wrong.
-  end
-
-  def virt_supported?
-    @conn.virt_supported?
-  end
-
-  #
-  # Checks if the connection is valid.
-  #
-  # @return [Boolean] `true` if the connection is valid, `false` otherwise.
-  #
-  def valid?
-    @conn.valid?
-  end
-
-  #
-  # Returns an array containing the nodes available in the Kubernetes cluster.
-  #
-  # @return [Array] The array of nodes.
-  #
-  def nodes
-    @conn.nodes
-  end
-
-  #
-  # Returns a watcher for nodes.
-  #
-  # @param opts [Hash] A hash with options for the watcher.
-  # @return [Kubeclient::Common::WatchStream] The watcher.
-  #
-  def watch_nodes(opts = {})
-    @conn.watch_nodes(opts)
-  end
-
-  #
-  # Returns an array containing the templates available in the KubeVirt environment.
-  #
-  # @return [Array] The array of templates.
-  #
-  def templates
-    @conn.templates
-  end
-
-  #
-  # Retrieves the template with the given name.
-  #
-  # @param name [String] The name of the template.
-  # @return [Object] The template object.
-  #
-  def template(name)
-    @conn.templates.get(name)
-  end
-
-  #
-  # Returns a watcher for templates.
-  #
-  # @param opts [Hash] A hash with options for the watcher.
-  # @return [Kubeclient::Common::WatchStream] The watcher.
-  #
-  def watch_templates(opts = {})
-    @conn.watch_templates(opts)
-  end
-
-  #
-  # Returns an array containing the virtual machines available in the KubeVirt environment.
-  #
-  # @return [Array] The array of virtual machines.
-  #
-  def vms
-    @conn.vms
-  end
-
-  #
-  # Retrieves the virtual machine with the given name.
-  #
-  # @param name [String] The name of the virtual machine.
-  # @return [Object] The virtual machine object.
-  #
-  def vm(name)
-    @conn.vms.get(name)
-  end
-
-  #
-  # Returns a watcher for virtual machines.
-  #
-  # @param opts [Hash] A hash with options for the watcher.
-  # @return [Kubeclient::Common::WatchStream] The watcher.
-  #
-  def watch_vms(opts = {})
-    @conn.watch_vms(opts)
-  end
-
-  #
-  # Returns an array containing the virtual machine instances available in the KubeVirt environment.
-  #
-  # @return [Array] The array of virtual machine instances.
-  #
-  def vm_instances
-    @conn.vminstances
-  end
-
-  #
-  # Retrieves the virtual machine instance with the given name.
-  #
-  # @param name [String] The name of the virtual machine.
-  # @return [Object] The virtual machine object.
-  #
-  def vm_instance(name)
-    @conn.vminstances.get(name)
-  end
-
-  #
-  # Returns a watcher for virtual machine instances.
-  #
-  # @param opts [Hash] A hash with options for the watcher.
-  # @return [Kubeclient::Common::WatchStream] The watcher.
-  #
-  def watch_vm_instances(opts = {})
-    @conn.watch_vminstances(opts)
-  end
-
-  #
-  # Deletes a virtual machine instance.
-  #
-  # @param name [String] The name of the virtual machine to delete.
-  #
-  def delete_vm_instance(name, namespace)
-    @conn.vminstances.destroy(name, namespace)
-  end
-end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb b/app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
index 622b6eb7..df996dcf 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
@@ -10,10 +10,9 @@ def prepare_for_clone_task
     raise MiqException::MiqProvisionError, "Provision request's destination virtual machine cannot be blank" if dest_name.blank?
     raise MiqException::MiqProvisionError, "A virtual machine with name '#{dest_name}' already exists" if source.ext_management_system.vms.where(:name => dest_name).any?
 
-    clone_options = {
+    {
       :name => dest_name,
     }
-    clone_options
   end
 
   def log_clone_options(clone_options)
@@ -26,18 +25,43 @@ def log_clone_options(clone_options)
   end
 
   def start_clone(options)
-    # Retrieve the details of the source template:
-    template = nil
-    source.with_provider_connection(:namespace => source.location) do |connection|
-      template = connection.template(source.name)
-      template.clone(user_options(options))
+    source.with_provider_connection do |connection|
+      # Retrieve the details of the source template:
+      template    = source.provider_object
+      namespace ||= source.location
 
-      vm = connection.vm(options[:name])
+      params    = values(template, user_options(options))
+      pvc_specs = template.objects.select { |o| o[:kind] == "PersistentVolumeClaim" }&.map(&:to_h)
+      vm_spec   = template.objects.detect { |o| o[:kind] == "VirtualMachine" }&.to_h
+      raise N_("No Virtual Machine defined in template") if vm_spec.nil?
 
-      phase_context[:new_vm_ems_ref] = vm.uid
+      param_substitution!(vm_spec, params)
+      vm_spec.deep_merge!(:spec => {:running => false}, :metadata => {:namespace => namespace})
+
+      create_persistent_volume_claims(pvc_specs, params, namespace) if pvc_specs.any?
+
+      begin
+        vm, _, _ = connection.create_namespaced_virtual_machine(namespace, vm_spec)
+        phase_context[:new_vm_ems_ref] = vm.metadata.uid
+      rescue
+        pvc_specs.each { |pvc| kubeclient.delete_persistent_volume_claim(pvc) }
+      end
     end
 
-    # TODO: check if we need to roll back if one object creation fails
+  end
+
+  private
+
+  def kubeclient
+    @kubeclient ||= source.ext_management_system.kubeclient
+  end
+
+  def create_persistent_volume_claims(pvc_specs, params, namespace)
+    pvc_specs.map do |pvc_spec|
+      param_substitution!(pvc_spec, params)
+      pvc_spec.deep_merge!(:metadata => {:namespace => namespace})
+      kubeclient.create_persistent_volume_claim(pvc_spec)
+    end
   end
 
   #
@@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
+    when Array
+      result.map { |v| param_substitution!(v, params) }
+    when String
+      result = sub_specific_object(params, object)
+    end
+    result
+  end
+
+  #
+  # Performs substitution on specific object.
+  #
+  # @params params [Hash] Containing parameter names and values used for substitution.
+  # @params object [String] Object on which substitution takes place.
+  # @returns [String] The outcome of substitution.
+  #
+  def sub_specific_object(params, object)
+    result = object
+    params.each_key do |name|
+      token = "${#{name.upcase}}"
+      os_token = "${{#{name.upcase}}}"
+      next unless object.include?(token) || object.include?(os_token)
+
+      result = if params[name].kind_of?(String)
+                 if object.include?(os_token)
+                   object.sub!(os_token, params[name])
+                 else
+                   object.sub!(token, params[name])
+                 end
+               else
+                 params[name]
+               end
+    end
+    result
+  end
 end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/refresh_memory.rb b/app/models/manageiq/providers/kubevirt/infra_manager/refresh_memory.rb
index fd030df7..03429f20 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/refresh_memory.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/refresh_memory.rb
@@ -88,6 +88,6 @@ def contains_notice?(notice)
   # Calculates the key that will be used to store a notice.
   #
   def notice_key(notice)
-    "#{notice.kind}:#{notice.resource_version}"
+    "#{notice.object.kind}:#{notice.object.metadata.resourceVersion}"
   end
 end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/refresh_worker/runner.rb b/app/models/manageiq/providers/kubevirt/infra_manager/refresh_worker/runner.rb
index dabafdfa..54e563b5 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/refresh_worker/runner.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/refresh_worker/runner.rb
@@ -105,10 +105,10 @@ def full_refresh
     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)
+    memory.add_list_version(:nodes, collector.nodes.resourceVersion)
+    memory.add_list_version(:vms, collector.vms.resourceVersion)
+    memory.add_list_version(:vm_instances, collector.vm_instances.resourceVersion)
+    memory.add_list_version(:templates, collector.templates.resourceVersion)
 
     manager.update(:last_refresh_error => nil, :last_refresh_date => Time.now.utc)
   rescue StandardError => error
@@ -144,7 +144,7 @@ def partial_refresh(notices)
     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}' " \
+          "Notice of kind '#{notice.object.kind}, id '#{notice.object.metadata.uid}', type '#{notice.type}' and version '#{notice.resource_version}' " \
           "has already been processed, will ignore it."
         )
         true
@@ -194,7 +194,7 @@ def partial_refresh(notices)
   # @return [Array] An array containing the notices that have the given kind.
   #
   def notices_of_kind(notices, kind)
-    notices.select { |notice| notice.kind == kind }
+    notices.select { |notice| notice.object.kind == kind }
   end
 
   #
@@ -206,12 +206,10 @@ def start_watches
 
     # 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
+    @watches << @manager.kubeclient.watch_nodes(:resource_version => memory.get_list_version(:nodes))
+    @watches << @manager.kubeclient("kubevirt.io/v1").watch_virtual_machines(:resource_version => memory.get_list_version(:vms))
+    @watches << @manager.kubeclient("kubevirt.io/v1").watch_virtual_machine_instances(:resource_version => memory.get_list_version(:vm_instances))
+    @watches << @manager.kubeclient("template.openshift.io/v1").watch_templates(:resource_version => memory.get_list_version(:templates))
 
     # Create the threads that run the watches and put the notices in the queue:
     @watchers = []
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/template.rb b/app/models/manageiq/providers/kubevirt/infra_manager/template.rb
index f5a2f60b..e2c24e3b 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/template.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/template.rb
@@ -10,4 +10,8 @@ class ManageIQ::Providers::Kubevirt::InfraManager::Template < ManageIQ::Provider
   def self.display_name(number = 1)
     n_('Template (Kubevirt)', 'Templates (Kubevirt)', number)
   end
+
+  def provider_object
+    ext_management_system.kubeclient("template.openshift.io/v1").get_template(name, location)
+  end
 end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations.rb b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations.rb
index 5de18866..4a63213a 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations.rb
@@ -9,18 +9,8 @@ module ManageIQ::Providers::Kubevirt::InfraManager::Vm::Operations
   end
 
   def raw_destroy
-    require 'fog/kubevirt'
-    ext_management_system.with_provider_connection(:namespace => location) do |connection|
-      # Retrieve the details of the virtual machine:
-      begin
-        vm_instance = connection.vm_instance(name)
-      rescue Fog::Kubevirt::Errors::ClientError
-        # the virtual machine instance doesn't exist
-        vm_instance = nil
-      end
-
-      # delete vm instance
-      connection.delete_vm_instance(name, location) unless vm_instance.nil?
+    with_provider_connection do |connection|
+      connection.delete_namespaced_virtual_machine(name, location, {})
     end
   end
 end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/guest.rb b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/guest.rb
index 3a7dad24..669c6955 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/guest.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/guest.rb
@@ -1,12 +1,14 @@
 module ManageIQ::Providers::Kubevirt::InfraManager::Vm::Operations::Guest
 
   def raw_reboot_guest
-    kubevirt = ext_management_system.parent_manager.connect(:service => "kubernetes", :path => "/apis/subresources.kubevirt.io", :version => "v1")
-    kubevirt.rest_client["namespaces/#{location}/virtualmachineinstances/#{name}/softreboot"].put({}.to_json, { 'Content-Type' => 'application/json' }.merge(kubevirt.get_headers))
+    with_provider_connection do |connection|
+      connection.v1_soft_reboot(name, location)
+    end
   end
 
   def raw_reset
-    kubevirt = ext_management_system.parent_manager.connect(:service => "kubernetes", :path => "/apis/subresources.kubevirt.io", :version => "v1")
-    kubevirt.rest_client["namespaces/#{location}/virtualmachines/#{name}/restart"].put({}.to_json, { 'Content-Type' => 'application/json' }.merge(kubevirt.get_headers))
+    with_provider_connection do |connection|
+      connection.v1_restart(name, location)
+    end
   end
-end
\ No newline at end of file
+end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/power.rb b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/power.rb
index a979fe14..319de817 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/power.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/power.rb
@@ -1,17 +1,14 @@
 module ManageIQ::Providers::Kubevirt::InfraManager::Vm::Operations::Power
   def raw_start
-    ext_management_system.with_provider_connection(:namespace => location) do |connection|
-      # Retrieve the details of the virtual machine:
-      vm = connection.vm(name)
-      vm.start
+    with_provider_connection do |connection|
+      start_options = Kubevirt::V1StartOptions.new
+      connection.v1_start(name, location, start_options)
     end
   end
 
   def raw_stop
-    ext_management_system.with_provider_connection(:namespace => location) do |connection|
-      # Retrieve the details of the virtual machine:
-      vm = connection.vm(name)
-      vm.stop
+    with_provider_connection do |connection|
+      connection.v1_stop(name, location)
     end
   end
-end
\ No newline at end of file
+end
diff --git a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/snapshot.rb b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/snapshot.rb
index 3f7d2d7b..728ad188 100644
--- a/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/snapshot.rb
+++ b/app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/snapshot.rb
@@ -1,19 +1,24 @@
 module ManageIQ::Providers::Kubevirt::InfraManager::Vm::Operations::Snapshot
   def raw_create_snapshot(snap_name, _desc = nil, _memory = false)
-    kubevirt = ext_management_system.parent_manager.connect(:service => "kubernetes", :path => "/apis/snapshot.kubevirt.io", :version => "v1alpha1")
-    kubevirt.create_virtual_machine_snapshot(
-      :metadata => {
-        :namespace => location,
-        :name      => snap_name
-      },
-      :spec => {
-        :source => {
-          :apiGroup => "kubevirt.io",
-          :kind     => "VirtualMachine",
-          :name     => name
-        }
-      }
-    )
+    with_provider_connection do |connection|
+      snapshot_spec = Kubevirt::V1beta1VirtualMachineSnapshot.new(
+        :api_version => "snapshot.kubevirt.io/v1beta1",
+        :kind        => "VirtualMachineSnapshot",
+        :metadata    => Kubevirt::K8sIoApimachineryPkgApisMetaV1ObjectMeta.new(
+          :name      => snap_name,
+          :namespace => location
+        ),
+        :spec        => Kubevirt::V1beta1VirtualMachineSnapshotSpec.new(
+          :source => Kubevirt::K8sIoApiCoreV1TypedLocalObjectReference.new(
+            :api_group => "kubevirt.io",
+            :kind      => "VirtualMachine",
+            :name      => name
+          )
+        )
+      )
+
+      connection.create_namespaced_virtual_machine_snapshot(location, snapshot_spec)
+    end
   end
 end
 
diff --git a/app/models/manageiq/providers/kubevirt/inventory/collector.rb b/app/models/manageiq/providers/kubevirt/inventory/collector.rb
index 20a2d4d9..f1a72836 100644
--- a/app/models/manageiq/providers/kubevirt/inventory/collector.rb
+++ b/app/models/manageiq/providers/kubevirt/inventory/collector.rb
@@ -25,29 +25,26 @@ def initialize(manager, refresh_target)
 
   def initialize_for_targeted_refresh
     name = @target.name
+    namespace = @target.location
     @nodes = {}
 
-    @manager.with_provider_connection(:namespace => @target.location) do |connection|
-      if @target.template?
-        @templates = [connection.template(name)]
-      else
-        @vms = [connection.vm(name)]
-        begin
-          @vm_instances = [connection.vm_instance(name)]
-        rescue
-          # target refresh of a vm might fail if it has no vm instance
-          _log.debug("The is no running vm resource for '#{name}'")
-        end
+    if @target.template?
+      @templates = [@manager.kubeclient("template.openshift.io/v1").template(name, namespace)]
+    else
+      @vms = [@manager.kubeclient("kubevirt.io/v1")..get_virtual_machine(name, namespace)]
+      begin
+        @vm_instances = [@manager.kubeclient("kubevirt.io/v1")..get_virtual_machine_instance(name, namespace)]
+      rescue
+        # target refresh of a vm might fail if it has no vm instance
+        _log.debug("The is no running vm resource for '#{name}'")
       end
     end
   end
 
   def initialize_for_full_refresh
-    @manager.with_provider_connection do |connection|
-      @nodes = connection.nodes
-      @vms = connection.vms
-      @vm_instances = connection.vm_instances
-      @templates = connection.templates
-    end
+    @nodes = @manager.kubeclient.get_nodes
+    @vms = @manager.kubeclient("kubevirt.io/v1").get_virtual_machines
+    @vm_instances = @manager.kubeclient("kubevirt.io/v1").get_virtual_machine_instances
+    @templates = @manager.kubeclient("template.openshift.io/v1").get_templates
   end
 end
diff --git a/app/models/manageiq/providers/kubevirt/inventory/parser.rb b/app/models/manageiq/providers/kubevirt/inventory/parser.rb
index e4822c62..5f8df6c4 100644
--- a/app/models/manageiq/providers/kubevirt/inventory/parser.rb
+++ b/app/models/manageiq/providers/kubevirt/inventory/parser.rb
@@ -17,6 +17,8 @@ class ManageIQ::Providers::Kubevirt::Inventory::Parser < ManageIQ::Providers::In
   #
   STORAGE_ID = '0'.freeze
 
+  OS_LABEL_SYMBOL = :'kubevirt.io/os'
+
   attr_reader :cluster_collection
   attr_reader :host_collection
   attr_reader :host_storage_collection
@@ -54,25 +56,31 @@ def process_nodes(objects)
 
   def process_node(object)
     # Get the basic information:
-    uid = object.uid
-    name = object.name
+    uid = object.metadata.uid
+    name = object.metadata.name
+
+    addresses = object.status.addresses.index_by(&:type)
+    hostname  = addresses["Hostname"]&.address
+    ipaddress = addresses["InternalIP"]&.address
 
     # Add the inventory object for the host:
     host_object = host_collection.find_or_build(uid)
     host_object.connection_state = 'connected'
     host_object.ems_cluster = cluster_collection.lazy_find(CLUSTER_ID)
     host_object.ems_ref = uid
-    host_object.hostname = object.hostname
-    host_object.ipaddress = object.ip_address
+    host_object.hostname = hostname
+    host_object.ipaddress = ipaddress
     host_object.name = name
     host_object.uid_ems = uid
 
+    node_info = object.status.nodeInfo
+
     # Add the inventory object for the operating system details:
     os_object = os_collection.find_or_build(host_object)
-    os_object.name = object.hostname
-    os_object.product_name = object.os_image
-    os_object.product_type = object.operating_system
-    os_object.version = object.kernel_version
+    os_object.name = hostname
+    os_object.product_name = node_info.osImage
+    os_object.product_type = node_info.operatingSystem
+    os_object.version = node_info.kernelVersion
 
     # Find the storage:
     storage_object = storage_collection.lazy_find(STORAGE_ID)
@@ -92,10 +100,13 @@ def process_vms(objects)
 
   def process_vm(object)
     # Process the domain:
-    vm_object = process_domain(object.namespace, object.memory, object.cpu_cores, object.uid, object.name)
+    spec = object.spec.template.spec
+    domain = spec.domain
+
+    vm_object = process_domain(object.metadata.namespace, domain.resources&.requests&.memory, domain.cpu, object.metadata.uid, object.metadata.name)
 
     # Add the inventory object for the OperatingSystem
-    process_os(vm_object, object.labels, object.annotations)
+    process_os(vm_object, object.metadata.labels, object.metadata.annotations)
 
     # The power status is initially off, it will be set to on later if the virtual machine instance exists:
     vm_object.raw_power_state = 'Succeeded'
@@ -109,23 +120,25 @@ def process_vm_instances(objects)
 
   def process_vm_instance(object)
     # Get the basic information:
-    uid = object.uid
-    name = object.name
+    uid = object.metadata.uid
+    name = object.metadata.name
 
     # Get the identifier of the virtual machine from the owner reference:
-    unless object.owner_name.nil?
+    owner_references = object.metadata.ownerReferences&.first
+    if owner_references&.name
       # seems like valid use case for now
-      uid = object.owner_uid
-      name = object.owner_name
+      uid  = owner_references.uid
+      name = owner_references.name
     end
 
     # Process the domain:
-    vm_object = process_domain(object.namespace, object.memory, object.cpu_cores, uid, name)
-    process_status(vm_object, object.ip_address, object.node_name)
+    vm_object = process_domain(object.metadata.namespace, object.spec.domain.memory&.guest, object.spec.domain.cpu&.cores, uid, name)
+
+    process_status(vm_object, object.status.interfaces&.first&.ipAddress, object.status.nodeName)
 
-    vm_object.host = host_collection.lazy_find(object.node_name, :ref => :by_name)
+    vm_object.host = host_collection.lazy_find(object.status.nodeName, :ref => :by_name)
 
-    vm_object.raw_power_state = object.status
+    vm_object.raw_power_state = object.status.phase
   end
 
   def process_domain(namespace, memory, cores, uid, name)
@@ -189,7 +202,7 @@ def process_templates(objects)
 
   def process_template(object)
     # Get the basic information:
-    uid = object.uid
+    uid = object.metadata.uid
     vm  = vm_from_objects(object.objects)
     return if vm.nil?
 
@@ -197,17 +210,17 @@ def process_template(object)
     template_object = template_collection.find_or_build(uid)
     template_object.connection_state = 'connected'
     template_object.ems_ref = uid
-    template_object.name = object.name
+    template_object.name = object.metadata.name
     template_object.raw_power_state = 'never'
     template_object.template = true
     template_object.uid_ems = uid
-    template_object.location = object.namespace
+    template_object.location = object.metadata.namespace
 
     # Add the inventory object for the hardware:
-    process_hardware(template_object, object.parameters, object.labels, vm.dig(:spec, :template, :spec, :domain))
+    process_hardware(template_object, object.parameters, object.metadata.labels, vm.dig(:spec, :template, :spec, :domain))
 
     # Add the inventory object for the OperatingSystem
-    process_os(template_object, object.labels, object.annotations)
+    process_os(template_object, object.metadata.labels, object.metadata.annotations)
   end
 
   def vm_from_objects(objects)
@@ -221,15 +234,13 @@ def vm_from_objects(objects)
   end
 
   def process_hardware(template_object, params, labels, domain)
-    require 'fog/kubevirt'
-    require 'fog/kubevirt/compute/models/template'
     hw_object = hw_collection.find_or_build(template_object)
     memory = default_value(params, 'MEMORY') || domain.dig(:memory, :guest)
     hw_object.memory_mb = parse_quantity(memory) / 1.megabytes.to_f if memory
     cpu = default_value(params, 'CPU_CORES') || domain.dig(:cpu, :cores)
     hw_object.cpu_cores_per_socket = cpu
     hw_object.cpu_total_cores = cpu
-    hw_object.guest_os = labels&.dig(Fog::Kubevirt::Compute::Template::OS_LABEL_SYMBOL)
+    hw_object.guest_os = labels&.dig(OS_LABEL_SYMBOL)
 
     # Add the inventory objects for the disk:
     process_disks(hw_object, domain)
@@ -256,10 +267,8 @@ def process_disks(hw_object, domain)
   end
 
   def process_os(template_object, labels, annotations)
-    require 'fog/kubevirt'
-    require 'fog/kubevirt/compute/models/template'
     os_object = vm_os_collection.find_or_build(template_object)
-    os_object.product_name = labels&.dig(Fog::Kubevirt::Compute::Template::OS_LABEL_SYMBOL)
+    os_object.product_name = labels&.dig(OS_LABEL_SYMBOL)
     tags = annotations&.dig(:tags) || []
     os_object.product_type = if tags.include?("linux")
                                "linux"
diff --git a/app/models/manageiq/providers/kubevirt/inventory/parser/partial_refresh.rb b/app/models/manageiq/providers/kubevirt/inventory/parser/partial_refresh.rb
index b2e58578..cf627d84 100644
--- a/app/models/manageiq/providers/kubevirt/inventory/parser/partial_refresh.rb
+++ b/app/models/manageiq/providers/kubevirt/inventory/parser/partial_refresh.rb
@@ -11,9 +11,9 @@ def parse
 
     # We need to find the identifiers of the objects *before* removing notices of type `DELETED`, because we need the
     # identifiers of all the objects, even of those that have been deleted.
-    host_ids = get_object_ids(nodes)
-    vm_ids = get_object_ids(vms)
-    template_ids = get_object_ids(templates)
+    host_ids = get_object_ids(nodes.map(&:object))
+    vm_ids = get_object_ids(vms.map(&:object))
+    template_ids = get_object_ids(templates.map(&:object))
 
     # Build the list of identifiers for built-in objects:
     cluster_ids = [CLUSTER_ID]
@@ -44,16 +44,16 @@ def parse
     add_builtin_storages
 
     # Process the real objects:
-    process_nodes(nodes)
-    process_vms(vms)
-    process_vm_instances(vm_instances)
-    process_templates(templates)
+    process_nodes(nodes.map(&:object))
+    process_vms(vms.map(&:object))
+    process_vm_instances(vm_instances.map(&:object))
+    process_templates(templates.map(&:object))
   end
 
   private
 
-  def get_object_ids(notices)
-    notices.map { |notice| notice.metadata.uid }.uniq
+  def get_object_ids(objects)
+    objects.map { |object| object.metadata.uid }.uniq
   end
 
   def discard_deleted_notices(notices)
diff --git a/app/models/manageiq/providers/kubevirt/inventory/parser/partial_target_refresh.rb b/app/models/manageiq/providers/kubevirt/inventory/parser/partial_target_refresh.rb
index f0307d47..39a48a47 100644
--- a/app/models/manageiq/providers/kubevirt/inventory/parser/partial_target_refresh.rb
+++ b/app/models/manageiq/providers/kubevirt/inventory/parser/partial_target_refresh.rb
@@ -44,6 +44,6 @@ def parse
   private
 
   def get_object_ids(objects)
-    objects.map { |o| o.uid }.uniq
+    objects.map { |o| o.metadata.uid }.uniq
   end
 end
diff --git a/manageiq-providers-kubevirt.gemspec b/manageiq-providers-kubevirt.gemspec
index fdb56d03..e655bc89 100644
--- a/manageiq-providers-kubevirt.gemspec
+++ b/manageiq-providers-kubevirt.gemspec
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
   spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
   spec.require_paths = ["lib"]
 
-  spec.add_dependency "fog-kubevirt",                  "~> 1.4"
+  spec.add_dependency "kubevirt", "~> 0.1.0"
   spec.add_dependency "manageiq-providers-kubernetes", "~> 0.1.0"
 
   spec.add_development_dependency "manageiq-style"
diff --git a/spec/fixtures/files/template-without-parameters.yml b/spec/fixtures/files/template-without-parameters.yml
index cd83f79d..fb72a303 100644
--- a/spec/fixtures/files/template-without-parameters.yml
+++ b/spec/fixtures/files/template-without-parameters.yml
@@ -3,6 +3,7 @@ kind: Template
 metadata:
   name: template-without-parameters
   namespace: default
+  uid: 7e6fb1ac-00ef-11e8-8840-525400b2cba8
   annotations:
     description: "OpenShift KubeVirt Cirros VM template"
     tags: "kubevirt,openshift,template,linux"
diff --git a/spec/models/manageiq/providers/kubevirt/infra_manager/provision/cloning_spec.rb b/spec/models/manageiq/providers/kubevirt/infra_manager/provision/cloning_spec.rb
index 090ae327..b8a04d46 100644
--- a/spec/models/manageiq/providers/kubevirt/infra_manager/provision/cloning_spec.rb
+++ b/spec/models/manageiq/providers/kubevirt/infra_manager/provision/cloning_spec.rb
@@ -6,25 +6,74 @@
 
 describe ManageIQ::Providers::Kubevirt::InfraManager::Provision do
   context "Cloning" do
+    let(:source)     { FactoryBot.create(:template_kubevirt, :location => namespace) }
+    let(:options)    { {:cores_per_socket => [1, "1"], :vm_memory => ["1024", "1024"], :root_password => "1234"} }
+    let(:connection) { double("Kubevirt::DefaultApi") }
+    let(:namespace)  { "openshift" }
+    let(:parameters) { [Kubeclient::Resource.new(:name => "NAME"), Kubeclient::Resource.new(:name => "CLOUD_USER_PASSWORD")] }
+    let(:vm_object)  { Kubeclient::Resource.new(:apiVersion => "kubevirt.io/v1", :kind => "VirtualMachine", :metadata => {:name => "${NAME}"}) }
+    let(:objects)    { [vm_object] }
+    let(:template) do
+      require "kubeclient"
+      Kubeclient::Resource.new(
+        :kind       => "Template",
+        :metadata   => {:name => "centos-stream8-desktop-large", :namespace => "openshift", :uid => "8c37cebc-c27c-4c39-ac89-777ddb2c1115"},
+        :objects    => objects,
+        :parameters => parameters
+      )
+    end
+
+    before do
+      allow(source).to receive(:provider_object).and_return(template)
+      subject.source  = source
+      subject.options = options
+    end
+
     it "calls clone on template" do
-      source = FactoryBot.create(:template_kubevirt)
-      subject.source = source
-      connection = double("connection")
+      connection = double("Kubevirt::DefaultApi")
 
-      template = double("template")
-      allow(template).to receive(:name).and_return("example")
+      require 'kubevirt'
+      new_vm = Kubevirt::V1VirtualMachine.new(:metadata => Kubevirt::K8sIoApimachineryPkgApisMetaV1ObjectMeta.new(:uid => SecureRandom.uuid))
+      allow(connection).to receive(:create_namespaced_virtual_machine).with(namespace, hash_including(:metadata => hash_including(:name => "test"))).and_return(new_vm, 200, {})
+      allow(source).to     receive(:with_provider_connection).and_yield(connection)
 
-      vm = double("vm")
-      allow(vm).to receive(:uid).and_return("7e6fb1ac-00ef-11e8-8840-525400b2cba8")
+      subject.start_clone(:name => "test")
 
-      allow(connection).to receive(:template).and_return(template)
-      allow(connection).to receive(:vm).and_return(vm)
-      allow(source).to receive(:with_provider_connection).and_yield(connection)
-      allow(source).to receive(:name).and_return("test")
+      expect(subject.phase_context[:new_vm_ems_ref]).to eq(new_vm.metadata.uid)
+    end
 
-      expect(template).to receive(:clone)
+    context "with persistent volume claims" do
+      let(:pvc_object) { Kubeclient::Resource.new(:kind => "PersistentVolumeClaim") }
+      let(:objects)    { [vm_object, pvc_object] }
 
-      subject.start_clone(:name => "test")
+      it "creates the persistent volume claims" do
+        connection = double("Kubevirt::DefaultApi")
+        kubeclient = double("Kubeclient")
+
+        require 'kubevirt'
+        new_vm = Kubevirt::V1VirtualMachine.new(:metadata => Kubevirt::K8sIoApimachineryPkgApisMetaV1ObjectMeta.new(:uid => SecureRandom.uuid))
+        allow(connection).to receive(:create_namespaced_virtual_machine).with(namespace, hash_including(:metadata => hash_including(:name => "test"))).and_return(new_vm, 200, {})
+        allow(source).to     receive(:with_provider_connection).and_yield(connection)
+        allow(subject).to    receive(:kubeclient).and_return(kubeclient)
+
+        expect(kubeclient).to receive(:create_persistent_volume_claim)
+
+        subject.start_clone(:name => "test")
+      end
+
+      it "cleans up pvcs on failure" do
+        connection = double("Kubevirt::DefaultApi")
+        kubeclient = double("Kubeclient")
+
+        allow(connection).to receive(:create_namespaced_virtual_machine).and_raise(RuntimeError)
+        allow(source).to     receive(:with_provider_connection).and_yield(connection)
+        allow(subject).to    receive(:kubeclient).and_return(kubeclient)
+
+        expect(kubeclient).to receive(:create_persistent_volume_claim)
+        expect(kubeclient).to receive(:delete_persistent_volume_claim)
+
+        subject.start_clone(:name => "test")
+      end
     end
   end
 end
diff --git a/spec/models/manageiq/providers/kubevirt/infra_manager/vm/operations_spec.rb b/spec/models/manageiq/providers/kubevirt/infra_manager/vm/operations_spec.rb
index f782237d..ba338a2e 100644
--- a/spec/models/manageiq/providers/kubevirt/infra_manager/vm/operations_spec.rb
+++ b/spec/models/manageiq/providers/kubevirt/infra_manager/vm/operations_spec.rb
@@ -45,7 +45,7 @@
   context '#raw_destroy' do
     let(:infra_manager) { container_manager.infra_manager }
     let(:vm) { FactoryBot.create(:vm_kubevirt, :ext_management_system => infra_manager) }
-    let(:connection) { double("connection") }
+    let(:connection) { double("Kubevirt::DefaultApi") }
     let(:vm_instance_metadata) { double("vm_instance_metadata", :namespace => "default") }
     let(:vm_instance) { double("vm_instance", :metadata => vm_instance_metadata) }
     let(:vm_metadata) { double("vm_metadata", :namespace => "default") }
@@ -57,11 +57,8 @@
 
     context 'running vm' do
       it 'removes an running vm from kubevirt provider' do
-        allow(connection).to receive(:vm_instance).and_return(vm_instance)
-        allow(connection).to receive(:vm).and_return(provider_vm)
         allow(infra_manager).to receive(:with_provider_connection).and_yield(connection)
-
-        expect(connection).to receive(:delete_vm_instance)
+        expect(connection).to receive(:delete_namespaced_virtual_machine).with(vm.name, vm.location, any_args)
 
         vm.raw_destroy
       end
@@ -69,13 +66,8 @@
 
     context 'stopped vm' do
       it 'removes a stopped vm from kubevirt provider' do
-        require 'fog/kubevirt'
-        error = Fog::Kubevirt::Errors::ClientError.new
-        allow(connection).to receive(:vm_instance).and_raise(error)
-        allow(connection).to receive(:vm).and_return(provider_vm)
         allow(infra_manager).to receive(:with_provider_connection).and_yield(connection)
-
-        expect(connection).not_to receive(:delete_vm_instance)
+        expect(connection).to receive(:delete_namespaced_virtual_machine).with(vm.name, vm.location, any_args)
 
         vm.raw_destroy
       end
diff --git a/spec/models/manageiq/providers/kubevirt/inventory/parse_vm_spec.rb b/spec/models/manageiq/providers/kubevirt/inventory/parse_vm_spec.rb
index e597fced..3557298c 100644
--- a/spec/models/manageiq/providers/kubevirt/inventory/parse_vm_spec.rb
+++ b/spec/models/manageiq/providers/kubevirt/inventory/parse_vm_spec.rb
@@ -35,17 +35,7 @@
       parser.instance_variable_set(:@hw_collection, hw_collection)
       parser.instance_variable_set(:@network_collection, network_collection)
 
-      source = double(
-        :uid        => "9f3a8f56-1bc8-11e8-a746-001a4a23138b",
-        :name       => "demo-vm",
-        :namespace  => "my-project",
-        :memory     => "64M",
-        :cpu_cores  => "2",
-        :ip_address => "10.128.0.18",
-        :node_name  => "vm-17-235.eng.lab.tlv.redhat.com",
-        :owner_name => nil,
-        :status     => "Running"
-      )
+      source = unprocessed_object("vm.json")
 
       parser.send(:process_vm_instance, source)
       expect(vm).to have_attributes(
@@ -55,7 +45,7 @@
         :uid_ems          => "9f3a8f56-1bc8-11e8-a746-001a4a23138b",
         :vendor           => ManageIQ::Providers::Kubevirt::Constants::VENDOR,
         :power_state      => "on",
-        :location         => "my-project",
+        :location         => "default",
         :connection_state => "connected",
       )
       expect(vm.host).to eq(host)
diff --git a/spec/models/manageiq/providers/kubevirt/inventory/parser_spec.rb b/spec/models/manageiq/providers/kubevirt/inventory/parser_spec.rb
index 57aff51a..2243ef02 100644
--- a/spec/models/manageiq/providers/kubevirt/inventory/parser_spec.rb
+++ b/spec/models/manageiq/providers/kubevirt/inventory/parser_spec.rb
@@ -29,19 +29,9 @@
       parser.instance_variable_set(:@vm_os_collection, os_collection)
       parser.instance_variable_set(:@disk_collection, disk_collection)
 
-      json = unprocessed_object("template.json")
-
-      source = double(
-        :name        => "example",
-        :uid         => "7e6fb1ac-00ef-11e8-8840-525400b2cba8",
-        :objects     => json.objects,
-        :parameters  => json.parameters,
-        :labels      => json.metadata.labels,
-        :annotations => json.metadata.annotations,
-        :namespace   => json.metadata.namespace
-      )
+      template = unprocessed_object("template.json")
 
-      parser.send(:process_template, source)
+      parser.send(:process_template, template)
 
       expect(temp).to have_attributes(
         :name             => "example",
@@ -98,19 +88,9 @@
       parser.instance_variable_set(:@vm_os_collection, os_collection)
       parser.instance_variable_set(:@disk_collection, disk_collection)
 
-      json = unprocessed_object("template_registry.json")
-
-      source = double(
-        :name        => "working",
-        :uid         => "7e6fb1ac-00ef-11e8-8840-525400b2cba8",
-        :objects     => json.objects,
-        :parameters  => json.parameters,
-        :labels      => json.metadata.labels,
-        :annotations => json.metadata.annotations,
-        :namespace   => json.metadata.namespace
-      )
+      template_registry = unprocessed_object("template_registry.json")
 
-      parser.send(:process_template, source)
+      parser.send(:process_template, template_registry)
 
       expect(disk1).to have_attributes(
         :device_name => "registryvolume",
@@ -150,19 +130,9 @@
       parser.instance_variable_set(:@vm_os_collection, os_collection)
       parser.instance_variable_set(:@disk_collection, disk_collection)
 
-      json = unprocessed_object("template-without-parameters.yml")
-
-      source = double(
-        :name        => "template-without-parameters",
-        :uid         => "7e6fb1ac-00ef-11e8-8840-525400b2cba8",
-        :objects     => json.objects,
-        :parameters  => json.parameters,
-        :labels      => json.metadata.labels,
-        :annotations => json.metadata.annotations,
-        :namespace   => json.metadata.namespace
-      )
+      template = unprocessed_object("template-without-parameters.yml")
 
-      parser.send(:process_template, source)
+      parser.send(:process_template, template)
 
       expect(temp).to have_attributes(
         :name             => "template-without-parameters",
diff --git a/spec/vcr_cassettes/manageiq/providers/kubevirt/infra_manager/refresher.yml b/spec/vcr_cassettes/manageiq/providers/kubevirt/infra_manager/refresher.yml
index ae8ecbd9..54da18f3 100644
--- a/spec/vcr_cassettes/manageiq/providers/kubevirt/infra_manager/refresher.yml
+++ b/spec/vcr_cassettes/manageiq/providers/kubevirt/infra_manager/refresher.yml
@@ -1,47 +1,5 @@
 ---
 http_interactions:
-- request:
-    method: get
-    uri: https://host.example.com:8443/api
-    body:
-      encoding: US-ASCII
-      string: ''
-    headers:
-      Accept:
-      - "*/*"
-      User-Agent:
-      - rest-client/2.1.0 (linux-gnu x86_64) ruby/3.3.7p123
-      Authorization:
-      - Bearer theToken
-      Accept-Encoding:
-      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
-  response:
-    status:
-      code: 200
-      message: OK
-    headers:
-      Audit-Id:
-      - 979a7ee5-fff5-4041-bfd9-037db27ddcea
-      Cache-Control:
-      - no-cache, private
-      Content-Type:
-      - application/json
-      Strict-Transport-Security:
-      - max-age=31536000; includeSubDomains; preload
-      X-Kubernetes-Pf-Flowschema-Uid:
-      - 1deef9d8-0e80-4942-b8f4-7f15731ec1ac
-      X-Kubernetes-Pf-Prioritylevel-Uid:
-      - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
-      Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
-      Content-Length:
-      - '137'
-    body:
-      encoding: UTF-8
-      string: '{"kind":"APIVersions","versions":["v1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.126.11:8443"}]}
-
-        '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/api/v1
@@ -63,7 +21,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - e0b4ba28-60eb-4d93-a7b4-6fa95515a9be
+      - 2afd24c7-dd77-46a1-9f0b-b05019302301
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -75,7 +33,7 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Transfer-Encoding:
       - chunked
     body:
@@ -83,7 +41,7 @@ http_interactions:
       string: '{"kind":"APIResourceList","groupVersion":"v1","resources":[{"name":"bindings","singularName":"binding","namespaced":true,"kind":"Binding","verbs":["create"]},{"name":"componentstatuses","singularName":"componentstatus","namespaced":false,"kind":"ComponentStatus","verbs":["get","list"],"shortNames":["cs"]},{"name":"configmaps","singularName":"configmap","namespaced":true,"kind":"ConfigMap","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["cm"],"storageVersionHash":"qFsyl6wFWjQ="},{"name":"endpoints","singularName":"endpoints","namespaced":true,"kind":"Endpoints","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["ep"],"storageVersionHash":"fWeeMqaN/OA="},{"name":"events","singularName":"event","namespaced":true,"kind":"Event","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["ev"],"storageVersionHash":"r2yiGXH7wu8="},{"name":"limitranges","singularName":"limitrange","namespaced":true,"kind":"LimitRange","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["limits"],"storageVersionHash":"EBKMFVe6cwo="},{"name":"namespaces","singularName":"namespace","namespaced":false,"kind":"Namespace","verbs":["create","delete","get","list","patch","update","watch"],"shortNames":["ns"],"storageVersionHash":"Q3oi5N2YM8M="},{"name":"namespaces/finalize","singularName":"","namespaced":false,"kind":"Namespace","verbs":["update"]},{"name":"namespaces/status","singularName":"","namespaced":false,"kind":"Namespace","verbs":["get","patch","update"]},{"name":"nodes","singularName":"node","namespaced":false,"kind":"Node","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["no"],"storageVersionHash":"XwShjMxG9Fs="},{"name":"nodes/proxy","singularName":"","namespaced":false,"kind":"NodeProxyOptions","verbs":["create","delete","get","patch","update"]},{"name":"nodes/status","singularName":"","namespaced":false,"kind":"Node","verbs":["get","patch","update"]},{"name":"persistentvolumeclaims","singularName":"persistentvolumeclaim","namespaced":true,"kind":"PersistentVolumeClaim","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["pvc"],"storageVersionHash":"QWTyNDq0dC4="},{"name":"persistentvolumeclaims/status","singularName":"","namespaced":true,"kind":"PersistentVolumeClaim","verbs":["get","patch","update"]},{"name":"persistentvolumes","singularName":"persistentvolume","namespaced":false,"kind":"PersistentVolume","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["pv"],"storageVersionHash":"HN/zwEC+JgM="},{"name":"persistentvolumes/status","singularName":"","namespaced":false,"kind":"PersistentVolume","verbs":["get","patch","update"]},{"name":"pods","singularName":"pod","namespaced":true,"kind":"Pod","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["po"],"categories":["all"],"storageVersionHash":"xPOwRZ+Yhw8="},{"name":"pods/attach","singularName":"","namespaced":true,"kind":"PodAttachOptions","verbs":["create","get"]},{"name":"pods/binding","singularName":"","namespaced":true,"kind":"Binding","verbs":["create"]},{"name":"pods/ephemeralcontainers","singularName":"","namespaced":true,"kind":"Pod","verbs":["get","patch","update"]},{"name":"pods/eviction","singularName":"","namespaced":true,"group":"policy","version":"v1","kind":"Eviction","verbs":["create"]},{"name":"pods/exec","singularName":"","namespaced":true,"kind":"PodExecOptions","verbs":["create","get"]},{"name":"pods/log","singularName":"","namespaced":true,"kind":"Pod","verbs":["get"]},{"name":"pods/portforward","singularName":"","namespaced":true,"kind":"PodPortForwardOptions","verbs":["create","get"]},{"name":"pods/proxy","singularName":"","namespaced":true,"kind":"PodProxyOptions","verbs":["create","delete","get","patch","update"]},{"name":"pods/status","singularName":"","namespaced":true,"kind":"Pod","verbs":["get","patch","update"]},{"name":"podtemplates","singularName":"podtemplate","namespaced":true,"kind":"PodTemplate","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"storageVersionHash":"LIXB2x4IFpk="},{"name":"replicationcontrollers","singularName":"replicationcontroller","namespaced":true,"kind":"ReplicationController","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["rc"],"categories":["all"],"storageVersionHash":"Jond2If31h0="},{"name":"replicationcontrollers/scale","singularName":"","namespaced":true,"group":"autoscaling","version":"v1","kind":"Scale","verbs":["get","patch","update"]},{"name":"replicationcontrollers/status","singularName":"","namespaced":true,"kind":"ReplicationController","verbs":["get","patch","update"]},{"name":"resourcequotas","singularName":"resourcequota","namespaced":true,"kind":"ResourceQuota","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["quota"],"storageVersionHash":"8uhSgffRX6w="},{"name":"resourcequotas/status","singularName":"","namespaced":true,"kind":"ResourceQuota","verbs":["get","patch","update"]},{"name":"secrets","singularName":"secret","namespaced":true,"kind":"Secret","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"storageVersionHash":"S6u1pOWzb84="},{"name":"serviceaccounts","singularName":"serviceaccount","namespaced":true,"kind":"ServiceAccount","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["sa"],"storageVersionHash":"pbx9ZvyFpBE="},{"name":"serviceaccounts/token","singularName":"","namespaced":true,"group":"authentication.k8s.io","version":"v1","kind":"TokenRequest","verbs":["create"]},{"name":"services","singularName":"service","namespaced":true,"kind":"Service","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"shortNames":["svc"],"categories":["all"],"storageVersionHash":"0/CO1lhkEBI="},{"name":"services/proxy","singularName":"","namespaced":true,"kind":"ServiceProxyOptions","verbs":["create","delete","get","patch","update"]},{"name":"services/status","singularName":"","namespaced":true,"kind":"Service","verbs":["get","patch","update"]}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/api/v1/nodes
@@ -105,7 +63,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - 414655fe-e45d-4e2d-a1e2-90282d5adf09
+      - 9f6c94cf-a832-49cd-922d-e272e1ec8243
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -117,12 +75,12 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Transfer-Encoding:
       - chunked
     body:
       encoding: UTF-8
-      string: '{"kind":"NodeList","apiVersion":"v1","metadata":{"resourceVersion":"1115115"},"items":[{"metadata":{"name":"crc","uid":"436c15c9-86cf-4fd6-9290-d219d2a59221","resourceVersion":"1114700","creationTimestamp":"2025-02-09T10:30:38Z","labels":{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","cpu-feature.node.kubevirt.io/3dnowprefetch":"true","cpu-feature.node.kubevirt.io/abm":"true","cpu-feature.node.kubevirt.io/adx":"true","cpu-feature.node.kubevirt.io/aes":"true","cpu-feature.node.kubevirt.io/amd-psfd":"true","cpu-feature.node.kubevirt.io/amd-ssbd":"true","cpu-feature.node.kubevirt.io/amd-stibp":"true","cpu-feature.node.kubevirt.io/apic":"true","cpu-feature.node.kubevirt.io/arat":"true","cpu-feature.node.kubevirt.io/arch-capabilities":"true","cpu-feature.node.kubevirt.io/auto-ibrs":"true","cpu-feature.node.kubevirt.io/avx":"true","cpu-feature.node.kubevirt.io/avx2":"true","cpu-feature.node.kubevirt.io/avx512-bf16":"true","cpu-feature.node.kubevirt.io/avx512-vpopcntdq":"true","cpu-feature.node.kubevirt.io/avx512bitalg":"true","cpu-feature.node.kubevirt.io/avx512bw":"true","cpu-feature.node.kubevirt.io/avx512cd":"true","cpu-feature.node.kubevirt.io/avx512dq":"true","cpu-feature.node.kubevirt.io/avx512f":"true","cpu-feature.node.kubevirt.io/avx512ifma":"true","cpu-feature.node.kubevirt.io/avx512vbmi":"true","cpu-feature.node.kubevirt.io/avx512vbmi2":"true","cpu-feature.node.kubevirt.io/avx512vl":"true","cpu-feature.node.kubevirt.io/avx512vnni":"true","cpu-feature.node.kubevirt.io/bmi1":"true","cpu-feature.node.kubevirt.io/bmi2":"true","cpu-feature.node.kubevirt.io/clflush":"true","cpu-feature.node.kubevirt.io/clflushopt":"true","cpu-feature.node.kubevirt.io/clwb":"true","cpu-feature.node.kubevirt.io/clzero":"true","cpu-feature.node.kubevirt.io/cmov":"true","cpu-feature.node.kubevirt.io/cmp_legacy":"true","cpu-feature.node.kubevirt.io/cr8legacy":"true","cpu-feature.node.kubevirt.io/cx16":"true","cpu-feature.node.kubevirt.io/cx8":"true","cpu-feature.node.kubevirt.io/de":"true","cpu-feature.node.kubevirt.io/erms":"true","cpu-feature.node.kubevirt.io/f16c":"true","cpu-feature.node.kubevirt.io/flush-l1d":"true","cpu-feature.node.kubevirt.io/fma":"true","cpu-feature.node.kubevirt.io/fpu":"true","cpu-feature.node.kubevirt.io/fsgsbase":"true","cpu-feature.node.kubevirt.io/fsrm":"true","cpu-feature.node.kubevirt.io/fxsr":"true","cpu-feature.node.kubevirt.io/fxsr_opt":"true","cpu-feature.node.kubevirt.io/gds-no":"true","cpu-feature.node.kubevirt.io/gfni":"true","cpu-feature.node.kubevirt.io/hypervisor":"true","cpu-feature.node.kubevirt.io/ibpb":"true","cpu-feature.node.kubevirt.io/ibrs":"true","cpu-feature.node.kubevirt.io/invpcid":"true","cpu-feature.node.kubevirt.io/la57":"true","cpu-feature.node.kubevirt.io/lahf_lm":"true","cpu-feature.node.kubevirt.io/lbrv":"true","cpu-feature.node.kubevirt.io/lfence-always-serializing":"true","cpu-feature.node.kubevirt.io/lm":"true","cpu-feature.node.kubevirt.io/mca":"true","cpu-feature.node.kubevirt.io/mce":"true","cpu-feature.node.kubevirt.io/mds-no":"true","cpu-feature.node.kubevirt.io/misalignsse":"true","cpu-feature.node.kubevirt.io/mmx":"true","cpu-feature.node.kubevirt.io/mmxext":"true","cpu-feature.node.kubevirt.io/movbe":"true","cpu-feature.node.kubevirt.io/msr":"true","cpu-feature.node.kubevirt.io/mtrr":"true","cpu-feature.node.kubevirt.io/no-nested-data-bp":"true","cpu-feature.node.kubevirt.io/npt":"true","cpu-feature.node.kubevirt.io/nrip-save":"true","cpu-feature.node.kubevirt.io/null-sel-clr-base":"true","cpu-feature.node.kubevirt.io/nx":"true","cpu-feature.node.kubevirt.io/osvw":"true","cpu-feature.node.kubevirt.io/pae":"true","cpu-feature.node.kubevirt.io/pat":"true","cpu-feature.node.kubevirt.io/pause-filter":"true","cpu-feature.node.kubevirt.io/pcid":"true","cpu-feature.node.kubevirt.io/pclmuldq":"true","cpu-feature.node.kubevirt.io/pdpe1gb":"true","cpu-feature.node.kubevirt.io/perfctr_core":"true","cpu-feature.node.kubevirt.io/pfthreshold":"true","cpu-feature.node.kubevirt.io/pge":"true","cpu-feature.node.kubevirt.io/pku":"true","cpu-feature.node.kubevirt.io/pni":"true","cpu-feature.node.kubevirt.io/popcnt":"true","cpu-feature.node.kubevirt.io/pschange-mc-no":"true","cpu-feature.node.kubevirt.io/pse":"true","cpu-feature.node.kubevirt.io/pse36":"true","cpu-feature.node.kubevirt.io/rdctl-no":"true","cpu-feature.node.kubevirt.io/rdpid":"true","cpu-feature.node.kubevirt.io/rdrand":"true","cpu-feature.node.kubevirt.io/rdseed":"true","cpu-feature.node.kubevirt.io/rdtscp":"true","cpu-feature.node.kubevirt.io/sep":"true","cpu-feature.node.kubevirt.io/sha-ni":"true","cpu-feature.node.kubevirt.io/skip-l1dfl-vmentry":"true","cpu-feature.node.kubevirt.io/smap":"true","cpu-feature.node.kubevirt.io/smep":"true","cpu-feature.node.kubevirt.io/spec-ctrl":"true","cpu-feature.node.kubevirt.io/ssbd":"true","cpu-feature.node.kubevirt.io/sse":"true","cpu-feature.node.kubevirt.io/sse2":"true","cpu-feature.node.kubevirt.io/sse4.1":"true","cpu-feature.node.kubevirt.io/sse4.2":"true","cpu-feature.node.kubevirt.io/sse4a":"true","cpu-feature.node.kubevirt.io/ssse3":"true","cpu-feature.node.kubevirt.io/stibp":"true","cpu-feature.node.kubevirt.io/stibp-always-on":"true","cpu-feature.node.kubevirt.io/svm":"true","cpu-feature.node.kubevirt.io/svme-addr-chk":"true","cpu-feature.node.kubevirt.io/syscall":"true","cpu-feature.node.kubevirt.io/tsc":"true","cpu-feature.node.kubevirt.io/tsc-deadline":"true","cpu-feature.node.kubevirt.io/tsc-scale":"true","cpu-feature.node.kubevirt.io/tsc_adjust":"true","cpu-feature.node.kubevirt.io/umip":"true","cpu-feature.node.kubevirt.io/v-vmsave-vmload":"true","cpu-feature.node.kubevirt.io/vaes":"true","cpu-feature.node.kubevirt.io/vgif":"true","cpu-feature.node.kubevirt.io/virt-ssbd":"true","cpu-feature.node.kubevirt.io/vmcb-clean":"true","cpu-feature.node.kubevirt.io/vme":"true","cpu-feature.node.kubevirt.io/vnmi":"true","cpu-feature.node.kubevirt.io/vpclmulqdq":"true","cpu-feature.node.kubevirt.io/wbnoinvd":"true","cpu-feature.node.kubevirt.io/x2apic":"true","cpu-feature.node.kubevirt.io/xgetbv1":"true","cpu-feature.node.kubevirt.io/xsave":"true","cpu-feature.node.kubevirt.io/xsavec":"true","cpu-feature.node.kubevirt.io/xsaveerptr":"true","cpu-feature.node.kubevirt.io/xsaveopt":"true","cpu-feature.node.kubevirt.io/xsaves":"true","cpu-model-migration.node.kubevirt.io/Broadwell-noTSX":"true","cpu-model-migration.node.kubevirt.io/Broadwell-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Dhyana":"true","cpu-model-migration.node.kubevirt.io/EPYC":"true","cpu-model-migration.node.kubevirt.io/EPYC-Genoa":"true","cpu-model-migration.node.kubevirt.io/EPYC-IBPB":"true","cpu-model-migration.node.kubevirt.io/EPYC-Milan":"true","cpu-model-migration.node.kubevirt.io/EPYC-Rome":"true","cpu-model-migration.node.kubevirt.io/Haswell-noTSX":"true","cpu-model-migration.node.kubevirt.io/Haswell-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Icelake-Server-noTSX":"true","cpu-model-migration.node.kubevirt.io/IvyBridge":"true","cpu-model-migration.node.kubevirt.io/IvyBridge-IBRS":"true","cpu-model-migration.node.kubevirt.io/Nehalem":"true","cpu-model-migration.node.kubevirt.io/Nehalem-IBRS":"true","cpu-model-migration.node.kubevirt.io/Opteron_G3":"true","cpu-model-migration.node.kubevirt.io/Penryn":"true","cpu-model-migration.node.kubevirt.io/SandyBridge":"true","cpu-model-migration.node.kubevirt.io/SandyBridge-IBRS":"true","cpu-model-migration.node.kubevirt.io/Skylake-Client-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Skylake-Server-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Westmere":"true","cpu-model-migration.node.kubevirt.io/Westmere-IBRS":"true","cpu-model.node.kubevirt.io/Broadwell-noTSX":"true","cpu-model.node.kubevirt.io/Broadwell-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Dhyana":"true","cpu-model.node.kubevirt.io/EPYC":"true","cpu-model.node.kubevirt.io/EPYC-Genoa":"true","cpu-model.node.kubevirt.io/EPYC-IBPB":"true","cpu-model.node.kubevirt.io/EPYC-Milan":"true","cpu-model.node.kubevirt.io/EPYC-Rome":"true","cpu-model.node.kubevirt.io/Haswell-noTSX":"true","cpu-model.node.kubevirt.io/Haswell-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Icelake-Server-noTSX":"true","cpu-model.node.kubevirt.io/IvyBridge":"true","cpu-model.node.kubevirt.io/IvyBridge-IBRS":"true","cpu-model.node.kubevirt.io/Nehalem":"true","cpu-model.node.kubevirt.io/Nehalem-IBRS":"true","cpu-model.node.kubevirt.io/Opteron_G3":"true","cpu-model.node.kubevirt.io/Penryn":"true","cpu-model.node.kubevirt.io/SandyBridge":"true","cpu-model.node.kubevirt.io/SandyBridge-IBRS":"true","cpu-model.node.kubevirt.io/Skylake-Client-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Skylake-Server-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Westmere":"true","cpu-model.node.kubevirt.io/Westmere-IBRS":"true","cpu-vendor.node.kubevirt.io/AMD":"true","cpumanager":"false","host-model-cpu.node.kubevirt.io/EPYC-Genoa":"true","host-model-required-features.node.kubevirt.io/arch-capabilities":"true","host-model-required-features.node.kubevirt.io/cmp_legacy":"true","host-model-required-features.node.kubevirt.io/flush-l1d":"true","host-model-required-features.node.kubevirt.io/gds-no":"true","host-model-required-features.node.kubevirt.io/hypervisor":"true","host-model-required-features.node.kubevirt.io/lbrv":"true","host-model-required-features.node.kubevirt.io/mds-no":"true","host-model-required-features.node.kubevirt.io/pause-filter":"true","host-model-required-features.node.kubevirt.io/pfthreshold":"true","host-model-required-features.node.kubevirt.io/pschange-mc-no":"true","host-model-required-features.node.kubevirt.io/rdctl-no":"true","host-model-required-features.node.kubevirt.io/skip-l1dfl-vmentry":"true","host-model-required-features.node.kubevirt.io/spec-ctrl":"true","host-model-required-features.node.kubevirt.io/ssbd":"true","host-model-required-features.node.kubevirt.io/stibp":"true","host-model-required-features.node.kubevirt.io/tsc-deadline":"true","host-model-required-features.node.kubevirt.io/tsc-scale":"true","host-model-required-features.node.kubevirt.io/tsc_adjust":"true","host-model-required-features.node.kubevirt.io/v-vmsave-vmload":"true","host-model-required-features.node.kubevirt.io/vgif":"true","host-model-required-features.node.kubevirt.io/virt-ssbd":"true","host-model-required-features.node.kubevirt.io/vmcb-clean":"true","host-model-required-features.node.kubevirt.io/x2apic":"true","hyperv.node.kubevirt.io/base":"true","hyperv.node.kubevirt.io/frequencies":"true","hyperv.node.kubevirt.io/ipi":"true","hyperv.node.kubevirt.io/reenlightenment":"true","hyperv.node.kubevirt.io/reset":"true","hyperv.node.kubevirt.io/runtime":"true","hyperv.node.kubevirt.io/synic":"true","hyperv.node.kubevirt.io/synic2":"true","hyperv.node.kubevirt.io/synictimer":"true","hyperv.node.kubevirt.io/time":"true","hyperv.node.kubevirt.io/tlbflush":"true","hyperv.node.kubevirt.io/vpindex":"true","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"crc","kubernetes.io/os":"linux","kubevirt.io/ksm-enabled":"false","kubevirt.io/schedulable":"true","node-role.kubernetes.io/control-plane":"","node-role.kubernetes.io/master":"","node-role.kubernetes.io/worker":"","node.openshift.io/os_id":"rhcos","topology.hostpath.csi/node":"crc"},"annotations":{"csi.volume.kubernetes.io/nodeid":"{\"kubevirt.io.hostpath-provisioner\":\"crc\"}","k8s.ovn.org/host-cidrs":"[\"192.168.126.11/24\",\"192.168.127.2/24\"]","k8s.ovn.org/l3-gateway-config":"{\"default\":{\"mode\":\"shared\",\"bridge-id\":\"br-ex\",\"interface-id\":\"br-ex_crc\",\"mac-address\":\"5a:94:ef:e4:0c:ee\",\"ip-addresses\":[\"192.168.127.2/24\"],\"ip-address\":\"192.168.127.2/24\",\"next-hops\":[\"192.168.127.1\"],\"next-hop\":\"192.168.127.1\",\"node-port-enable\":\"true\",\"vlan-id\":\"0\"}}","k8s.ovn.org/network-ids":"{\"default\":\"0\"}","k8s.ovn.org/node-chassis-id":"1d5906ba-b111-4f75-bb53-27081dee4912","k8s.ovn.org/node-gateway-router-lrp-ifaddrs":"{\"default\":{\"ipv4\":\"100.64.0.2/16\"}}","k8s.ovn.org/node-id":"2","k8s.ovn.org/node-masquerade-subnet":"{\"ipv4\":\"169.254.0.0/17\",\"ipv6\":\"fd69::/112\"}","k8s.ovn.org/node-mgmt-port-mac-addresses":"{\"default\":\"4a:d3:c4:d7:10:a4\"}","k8s.ovn.org/node-primary-ifaddr":"{\"ipv4\":\"192.168.127.2/24\"}","k8s.ovn.org/node-subnets":"{\"default\":[\"10.217.0.0/23\"]}","k8s.ovn.org/node-transit-switch-port-ifaddr":"{\"ipv4\":\"100.88.0.2/16\"}","k8s.ovn.org/remote-zone-migrated":"crc","k8s.ovn.org/zone-name":"crc","kubevirt.io/heartbeat":"2025-02-26T19:03:19Z","kubevirt.io/ksm-handler-managed":"false","machineconfiguration.openshift.io/controlPlaneTopology":"SingleReplica","machineconfiguration.openshift.io/currentConfig":"rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/desiredConfig":"rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/desiredDrain":"uncordon-rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/lastAppliedDrain":"uncordon-rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/lastObservedServerCAAnnotation":"false","machineconfiguration.openshift.io/lastSyncedControllerConfigResourceVersion":"1103865","machineconfiguration.openshift.io/post-config-action":"","machineconfiguration.openshift.io/reason":"","machineconfiguration.openshift.io/state":"Done","volumes.kubernetes.io/controller-managed-attach-detach":"true"},"managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2025-02-09T10:30:38Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:volumes.kubernetes.io/controller-managed-attach-detach":{}},"f:labels":{".":{},"f:beta.kubernetes.io/arch":{},"f:beta.kubernetes.io/os":{},"f:kubernetes.io/arch":{},"f:kubernetes.io/hostname":{},"f:kubernetes.io/os":{},"f:node-role.kubernetes.io/control-plane":{},"f:node-role.kubernetes.io/master":{},"f:node.openshift.io/os_id":{}}}}},{"manager":"crc","operation":"Update","apiVersion":"v1","time":"2025-02-24T20:22:03Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:k8s.ovn.org/host-cidrs":{},"f:k8s.ovn.org/l3-gateway-config":{},"f:k8s.ovn.org/network-ids":{},"f:k8s.ovn.org/node-chassis-id":{},"f:k8s.ovn.org/node-gateway-router-lrp-ifaddrs":{},"f:k8s.ovn.org/node-id":{},"f:k8s.ovn.org/node-masquerade-subnet":{},"f:k8s.ovn.org/node-mgmt-port-mac-addresses":{},"f:k8s.ovn.org/node-primary-ifaddr":{},"f:k8s.ovn.org/node-subnets":{},"f:k8s.ovn.org/node-transit-switch-port-ifaddr":{},"f:k8s.ovn.org/remote-zone-migrated":{},"f:k8s.ovn.org/zone-name":{}}}},"subresource":"status"},{"manager":"machine-config-controller","operation":"Update","apiVersion":"v1","time":"2025-02-24T20:23:27Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:machineconfiguration.openshift.io/controlPlaneTopology":{},"f:machineconfiguration.openshift.io/desiredConfig":{},"f:machineconfiguration.openshift.io/lastAppliedDrain":{}},"f:labels":{"f:node-role.kubernetes.io/worker":{}}}}},{"manager":"machine-config-daemon","operation":"Update","apiVersion":"v1","time":"2025-02-26T18:36:35Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:machineconfiguration.openshift.io/currentConfig":{},"f:machineconfiguration.openshift.io/desiredDrain":{},"f:machineconfiguration.openshift.io/lastObservedServerCAAnnotation":{},"f:machineconfiguration.openshift.io/lastSyncedControllerConfigResourceVersion":{},"f:machineconfiguration.openshift.io/post-config-action":{},"f:machineconfiguration.openshift.io/reason":{},"f:machineconfiguration.openshift.io/state":{}}}}},{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2025-02-26T19:01:56Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:csi.volume.kubernetes.io/nodeid":{}},"f:labels":{"f:topology.hostpath.csi/node":{}}},"f:status":{"f:allocatable":{"f:cpu":{},"f:devices.kubevirt.io/kvm":{},"f:devices.kubevirt.io/tun":{},"f:devices.kubevirt.io/vhost-net":{},"f:ephemeral-storage":{},"f:memory":{}},"f:capacity":{"f:cpu":{},"f:devices.kubevirt.io/kvm":{},"f:devices.kubevirt.io/tun":{},"f:devices.kubevirt.io/vhost-net":{},"f:ephemeral-storage":{},"f:memory":{}},"f:conditions":{"k:{\"type\":\"DiskPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"MemoryPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"PIDPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"Ready\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}}},"f:images":{},"f:nodeInfo":{"f:bootID":{},"f:systemUUID":{}}}},"subresource":"status"},{"manager":"virt-handler","operation":"Update","apiVersion":"v1","time":"2025-02-26T19:03:19Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:kubevirt.io/heartbeat":{},"f:kubevirt.io/ksm-handler-managed":{}},"f:labels":{"f:cpu-feature.node.kubevirt.io/3dnowprefetch":{},"f:cpu-feature.node.kubevirt.io/abm":{},"f:cpu-feature.node.kubevirt.io/adx":{},"f:cpu-feature.node.kubevirt.io/aes":{},"f:cpu-feature.node.kubevirt.io/amd-psfd":{},"f:cpu-feature.node.kubevirt.io/amd-ssbd":{},"f:cpu-feature.node.kubevirt.io/amd-stibp":{},"f:cpu-feature.node.kubevirt.io/apic":{},"f:cpu-feature.node.kubevirt.io/arat":{},"f:cpu-feature.node.kubevirt.io/arch-capabilities":{},"f:cpu-feature.node.kubevirt.io/auto-ibrs":{},"f:cpu-feature.node.kubevirt.io/avx":{},"f:cpu-feature.node.kubevirt.io/avx2":{},"f:cpu-feature.node.kubevirt.io/avx512-bf16":{},"f:cpu-feature.node.kubevirt.io/avx512-vpopcntdq":{},"f:cpu-feature.node.kubevirt.io/avx512bitalg":{},"f:cpu-feature.node.kubevirt.io/avx512bw":{},"f:cpu-feature.node.kubevirt.io/avx512cd":{},"f:cpu-feature.node.kubevirt.io/avx512dq":{},"f:cpu-feature.node.kubevirt.io/avx512f":{},"f:cpu-feature.node.kubevirt.io/avx512ifma":{},"f:cpu-feature.node.kubevirt.io/avx512vbmi":{},"f:cpu-feature.node.kubevirt.io/avx512vbmi2":{},"f:cpu-feature.node.kubevirt.io/avx512vl":{},"f:cpu-feature.node.kubevirt.io/avx512vnni":{},"f:cpu-feature.node.kubevirt.io/bmi1":{},"f:cpu-feature.node.kubevirt.io/bmi2":{},"f:cpu-feature.node.kubevirt.io/clflush":{},"f:cpu-feature.node.kubevirt.io/clflushopt":{},"f:cpu-feature.node.kubevirt.io/clwb":{},"f:cpu-feature.node.kubevirt.io/clzero":{},"f:cpu-feature.node.kubevirt.io/cmov":{},"f:cpu-feature.node.kubevirt.io/cmp_legacy":{},"f:cpu-feature.node.kubevirt.io/cr8legacy":{},"f:cpu-feature.node.kubevirt.io/cx16":{},"f:cpu-feature.node.kubevirt.io/cx8":{},"f:cpu-feature.node.kubevirt.io/de":{},"f:cpu-feature.node.kubevirt.io/erms":{},"f:cpu-feature.node.kubevirt.io/f16c":{},"f:cpu-feature.node.kubevirt.io/flush-l1d":{},"f:cpu-feature.node.kubevirt.io/fma":{},"f:cpu-feature.node.kubevirt.io/fpu":{},"f:cpu-feature.node.kubevirt.io/fsgsbase":{},"f:cpu-feature.node.kubevirt.io/fsrm":{},"f:cpu-feature.node.kubevirt.io/fxsr":{},"f:cpu-feature.node.kubevirt.io/fxsr_opt":{},"f:cpu-feature.node.kubevirt.io/gds-no":{},"f:cpu-feature.node.kubevirt.io/gfni":{},"f:cpu-feature.node.kubevirt.io/hypervisor":{},"f:cpu-feature.node.kubevirt.io/ibpb":{},"f:cpu-feature.node.kubevirt.io/ibrs":{},"f:cpu-feature.node.kubevirt.io/invpcid":{},"f:cpu-feature.node.kubevirt.io/la57":{},"f:cpu-feature.node.kubevirt.io/lahf_lm":{},"f:cpu-feature.node.kubevirt.io/lbrv":{},"f:cpu-feature.node.kubevirt.io/lfence-always-serializing":{},"f:cpu-feature.node.kubevirt.io/lm":{},"f:cpu-feature.node.kubevirt.io/mca":{},"f:cpu-feature.node.kubevirt.io/mce":{},"f:cpu-feature.node.kubevirt.io/mds-no":{},"f:cpu-feature.node.kubevirt.io/misalignsse":{},"f:cpu-feature.node.kubevirt.io/mmx":{},"f:cpu-feature.node.kubevirt.io/mmxext":{},"f:cpu-feature.node.kubevirt.io/movbe":{},"f:cpu-feature.node.kubevirt.io/msr":{},"f:cpu-feature.node.kubevirt.io/mtrr":{},"f:cpu-feature.node.kubevirt.io/no-nested-data-bp":{},"f:cpu-feature.node.kubevirt.io/npt":{},"f:cpu-feature.node.kubevirt.io/nrip-save":{},"f:cpu-feature.node.kubevirt.io/null-sel-clr-base":{},"f:cpu-feature.node.kubevirt.io/nx":{},"f:cpu-feature.node.kubevirt.io/osvw":{},"f:cpu-feature.node.kubevirt.io/pae":{},"f:cpu-feature.node.kubevirt.io/pat":{},"f:cpu-feature.node.kubevirt.io/pause-filter":{},"f:cpu-feature.node.kubevirt.io/pcid":{},"f:cpu-feature.node.kubevirt.io/pclmuldq":{},"f:cpu-feature.node.kubevirt.io/pdpe1gb":{},"f:cpu-feature.node.kubevirt.io/perfctr_core":{},"f:cpu-feature.node.kubevirt.io/pfthreshold":{},"f:cpu-feature.node.kubevirt.io/pge":{},"f:cpu-feature.node.kubevirt.io/pku":{},"f:cpu-feature.node.kubevirt.io/pni":{},"f:cpu-feature.node.kubevirt.io/popcnt":{},"f:cpu-feature.node.kubevirt.io/pschange-mc-no":{},"f:cpu-feature.node.kubevirt.io/pse":{},"f:cpu-feature.node.kubevirt.io/pse36":{},"f:cpu-feature.node.kubevirt.io/rdctl-no":{},"f:cpu-feature.node.kubevirt.io/rdpid":{},"f:cpu-feature.node.kubevirt.io/rdrand":{},"f:cpu-feature.node.kubevirt.io/rdseed":{},"f:cpu-feature.node.kubevirt.io/rdtscp":{},"f:cpu-feature.node.kubevirt.io/sep":{},"f:cpu-feature.node.kubevirt.io/sha-ni":{},"f:cpu-feature.node.kubevirt.io/skip-l1dfl-vmentry":{},"f:cpu-feature.node.kubevirt.io/smap":{},"f:cpu-feature.node.kubevirt.io/smep":{},"f:cpu-feature.node.kubevirt.io/spec-ctrl":{},"f:cpu-feature.node.kubevirt.io/ssbd":{},"f:cpu-feature.node.kubevirt.io/sse":{},"f:cpu-feature.node.kubevirt.io/sse2":{},"f:cpu-feature.node.kubevirt.io/sse4.1":{},"f:cpu-feature.node.kubevirt.io/sse4.2":{},"f:cpu-feature.node.kubevirt.io/sse4a":{},"f:cpu-feature.node.kubevirt.io/ssse3":{},"f:cpu-feature.node.kubevirt.io/stibp":{},"f:cpu-feature.node.kubevirt.io/stibp-always-on":{},"f:cpu-feature.node.kubevirt.io/svm":{},"f:cpu-feature.node.kubevirt.io/svme-addr-chk":{},"f:cpu-feature.node.kubevirt.io/syscall":{},"f:cpu-feature.node.kubevirt.io/tsc":{},"f:cpu-feature.node.kubevirt.io/tsc-deadline":{},"f:cpu-feature.node.kubevirt.io/tsc-scale":{},"f:cpu-feature.node.kubevirt.io/tsc_adjust":{},"f:cpu-feature.node.kubevirt.io/umip":{},"f:cpu-feature.node.kubevirt.io/v-vmsave-vmload":{},"f:cpu-feature.node.kubevirt.io/vaes":{},"f:cpu-feature.node.kubevirt.io/vgif":{},"f:cpu-feature.node.kubevirt.io/virt-ssbd":{},"f:cpu-feature.node.kubevirt.io/vmcb-clean":{},"f:cpu-feature.node.kubevirt.io/vme":{},"f:cpu-feature.node.kubevirt.io/vnmi":{},"f:cpu-feature.node.kubevirt.io/vpclmulqdq":{},"f:cpu-feature.node.kubevirt.io/wbnoinvd":{},"f:cpu-feature.node.kubevirt.io/x2apic":{},"f:cpu-feature.node.kubevirt.io/xgetbv1":{},"f:cpu-feature.node.kubevirt.io/xsave":{},"f:cpu-feature.node.kubevirt.io/xsavec":{},"f:cpu-feature.node.kubevirt.io/xsaveerptr":{},"f:cpu-feature.node.kubevirt.io/xsaveopt":{},"f:cpu-feature.node.kubevirt.io/xsaves":{},"f:cpu-model-migration.node.kubevirt.io/Broadwell-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/Broadwell-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Dhyana":{},"f:cpu-model-migration.node.kubevirt.io/EPYC":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Genoa":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-IBPB":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Milan":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Rome":{},"f:cpu-model-migration.node.kubevirt.io/Haswell-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/Haswell-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Icelake-Server-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/IvyBridge":{},"f:cpu-model-migration.node.kubevirt.io/IvyBridge-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Nehalem":{},"f:cpu-model-migration.node.kubevirt.io/Nehalem-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Opteron_G3":{},"f:cpu-model-migration.node.kubevirt.io/Penryn":{},"f:cpu-model-migration.node.kubevirt.io/SandyBridge":{},"f:cpu-model-migration.node.kubevirt.io/SandyBridge-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Skylake-Client-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Skylake-Server-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Westmere":{},"f:cpu-model-migration.node.kubevirt.io/Westmere-IBRS":{},"f:cpu-model.node.kubevirt.io/Broadwell-noTSX":{},"f:cpu-model.node.kubevirt.io/Broadwell-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Dhyana":{},"f:cpu-model.node.kubevirt.io/EPYC":{},"f:cpu-model.node.kubevirt.io/EPYC-Genoa":{},"f:cpu-model.node.kubevirt.io/EPYC-IBPB":{},"f:cpu-model.node.kubevirt.io/EPYC-Milan":{},"f:cpu-model.node.kubevirt.io/EPYC-Rome":{},"f:cpu-model.node.kubevirt.io/Haswell-noTSX":{},"f:cpu-model.node.kubevirt.io/Haswell-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Icelake-Server-noTSX":{},"f:cpu-model.node.kubevirt.io/IvyBridge":{},"f:cpu-model.node.kubevirt.io/IvyBridge-IBRS":{},"f:cpu-model.node.kubevirt.io/Nehalem":{},"f:cpu-model.node.kubevirt.io/Nehalem-IBRS":{},"f:cpu-model.node.kubevirt.io/Opteron_G3":{},"f:cpu-model.node.kubevirt.io/Penryn":{},"f:cpu-model.node.kubevirt.io/SandyBridge":{},"f:cpu-model.node.kubevirt.io/SandyBridge-IBRS":{},"f:cpu-model.node.kubevirt.io/Skylake-Client-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Skylake-Server-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Westmere":{},"f:cpu-model.node.kubevirt.io/Westmere-IBRS":{},"f:cpu-vendor.node.kubevirt.io/AMD":{},"f:cpumanager":{},"f:host-model-cpu.node.kubevirt.io/EPYC-Genoa":{},"f:host-model-required-features.node.kubevirt.io/arch-capabilities":{},"f:host-model-required-features.node.kubevirt.io/cmp_legacy":{},"f:host-model-required-features.node.kubevirt.io/flush-l1d":{},"f:host-model-required-features.node.kubevirt.io/gds-no":{},"f:host-model-required-features.node.kubevirt.io/hypervisor":{},"f:host-model-required-features.node.kubevirt.io/lbrv":{},"f:host-model-required-features.node.kubevirt.io/mds-no":{},"f:host-model-required-features.node.kubevirt.io/pause-filter":{},"f:host-model-required-features.node.kubevirt.io/pfthreshold":{},"f:host-model-required-features.node.kubevirt.io/pschange-mc-no":{},"f:host-model-required-features.node.kubevirt.io/rdctl-no":{},"f:host-model-required-features.node.kubevirt.io/skip-l1dfl-vmentry":{},"f:host-model-required-features.node.kubevirt.io/spec-ctrl":{},"f:host-model-required-features.node.kubevirt.io/ssbd":{},"f:host-model-required-features.node.kubevirt.io/stibp":{},"f:host-model-required-features.node.kubevirt.io/tsc-deadline":{},"f:host-model-required-features.node.kubevirt.io/tsc-scale":{},"f:host-model-required-features.node.kubevirt.io/tsc_adjust":{},"f:host-model-required-features.node.kubevirt.io/v-vmsave-vmload":{},"f:host-model-required-features.node.kubevirt.io/vgif":{},"f:host-model-required-features.node.kubevirt.io/virt-ssbd":{},"f:host-model-required-features.node.kubevirt.io/vmcb-clean":{},"f:host-model-required-features.node.kubevirt.io/x2apic":{},"f:hyperv.node.kubevirt.io/base":{},"f:hyperv.node.kubevirt.io/frequencies":{},"f:hyperv.node.kubevirt.io/ipi":{},"f:hyperv.node.kubevirt.io/reenlightenment":{},"f:hyperv.node.kubevirt.io/reset":{},"f:hyperv.node.kubevirt.io/runtime":{},"f:hyperv.node.kubevirt.io/synic":{},"f:hyperv.node.kubevirt.io/synic2":{},"f:hyperv.node.kubevirt.io/synictimer":{},"f:hyperv.node.kubevirt.io/time":{},"f:hyperv.node.kubevirt.io/tlbflush":{},"f:hyperv.node.kubevirt.io/vpindex":{},"f:kubevirt.io/ksm-enabled":{},"f:kubevirt.io/schedulable":{}}}}}]},"spec":{},"status":{"capacity":{"cpu":"8","devices.kubevirt.io/kvm":"1k","devices.kubevirt.io/tun":"1k","devices.kubevirt.io/vhost-net":"1k","ephemeral-storage":"133626860Ki","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"24600668Ki","pods":"250"},"allocatable":{"cpu":"7800m","devices.kubevirt.io/kvm":"1k","devices.kubevirt.io/tun":"1k","devices.kubevirt.io/vhost-net":"1k","ephemeral-storage":"122783512373","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"24139868Ki","pods":"250"},"conditions":[{"type":"MemoryPressure","status":"False","lastHeartbeatTime":"2025-02-26T19:01:56Z","lastTransitionTime":"2025-02-24T20:22:04Z","reason":"KubeletHasSufficientMemory","message":"kubelet
+      string: '{"kind":"NodeList","apiVersion":"v1","metadata":{"resourceVersion":"1115929"},"items":[{"metadata":{"name":"crc","uid":"436c15c9-86cf-4fd6-9290-d219d2a59221","resourceVersion":"1115305","creationTimestamp":"2025-02-09T10:30:38Z","labels":{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","cpu-feature.node.kubevirt.io/3dnowprefetch":"true","cpu-feature.node.kubevirt.io/abm":"true","cpu-feature.node.kubevirt.io/adx":"true","cpu-feature.node.kubevirt.io/aes":"true","cpu-feature.node.kubevirt.io/amd-psfd":"true","cpu-feature.node.kubevirt.io/amd-ssbd":"true","cpu-feature.node.kubevirt.io/amd-stibp":"true","cpu-feature.node.kubevirt.io/apic":"true","cpu-feature.node.kubevirt.io/arat":"true","cpu-feature.node.kubevirt.io/arch-capabilities":"true","cpu-feature.node.kubevirt.io/auto-ibrs":"true","cpu-feature.node.kubevirt.io/avx":"true","cpu-feature.node.kubevirt.io/avx2":"true","cpu-feature.node.kubevirt.io/avx512-bf16":"true","cpu-feature.node.kubevirt.io/avx512-vpopcntdq":"true","cpu-feature.node.kubevirt.io/avx512bitalg":"true","cpu-feature.node.kubevirt.io/avx512bw":"true","cpu-feature.node.kubevirt.io/avx512cd":"true","cpu-feature.node.kubevirt.io/avx512dq":"true","cpu-feature.node.kubevirt.io/avx512f":"true","cpu-feature.node.kubevirt.io/avx512ifma":"true","cpu-feature.node.kubevirt.io/avx512vbmi":"true","cpu-feature.node.kubevirt.io/avx512vbmi2":"true","cpu-feature.node.kubevirt.io/avx512vl":"true","cpu-feature.node.kubevirt.io/avx512vnni":"true","cpu-feature.node.kubevirt.io/bmi1":"true","cpu-feature.node.kubevirt.io/bmi2":"true","cpu-feature.node.kubevirt.io/clflush":"true","cpu-feature.node.kubevirt.io/clflushopt":"true","cpu-feature.node.kubevirt.io/clwb":"true","cpu-feature.node.kubevirt.io/clzero":"true","cpu-feature.node.kubevirt.io/cmov":"true","cpu-feature.node.kubevirt.io/cmp_legacy":"true","cpu-feature.node.kubevirt.io/cr8legacy":"true","cpu-feature.node.kubevirt.io/cx16":"true","cpu-feature.node.kubevirt.io/cx8":"true","cpu-feature.node.kubevirt.io/de":"true","cpu-feature.node.kubevirt.io/erms":"true","cpu-feature.node.kubevirt.io/f16c":"true","cpu-feature.node.kubevirt.io/flush-l1d":"true","cpu-feature.node.kubevirt.io/fma":"true","cpu-feature.node.kubevirt.io/fpu":"true","cpu-feature.node.kubevirt.io/fsgsbase":"true","cpu-feature.node.kubevirt.io/fsrm":"true","cpu-feature.node.kubevirt.io/fxsr":"true","cpu-feature.node.kubevirt.io/fxsr_opt":"true","cpu-feature.node.kubevirt.io/gds-no":"true","cpu-feature.node.kubevirt.io/gfni":"true","cpu-feature.node.kubevirt.io/hypervisor":"true","cpu-feature.node.kubevirt.io/ibpb":"true","cpu-feature.node.kubevirt.io/ibrs":"true","cpu-feature.node.kubevirt.io/invpcid":"true","cpu-feature.node.kubevirt.io/la57":"true","cpu-feature.node.kubevirt.io/lahf_lm":"true","cpu-feature.node.kubevirt.io/lbrv":"true","cpu-feature.node.kubevirt.io/lfence-always-serializing":"true","cpu-feature.node.kubevirt.io/lm":"true","cpu-feature.node.kubevirt.io/mca":"true","cpu-feature.node.kubevirt.io/mce":"true","cpu-feature.node.kubevirt.io/mds-no":"true","cpu-feature.node.kubevirt.io/misalignsse":"true","cpu-feature.node.kubevirt.io/mmx":"true","cpu-feature.node.kubevirt.io/mmxext":"true","cpu-feature.node.kubevirt.io/movbe":"true","cpu-feature.node.kubevirt.io/msr":"true","cpu-feature.node.kubevirt.io/mtrr":"true","cpu-feature.node.kubevirt.io/no-nested-data-bp":"true","cpu-feature.node.kubevirt.io/npt":"true","cpu-feature.node.kubevirt.io/nrip-save":"true","cpu-feature.node.kubevirt.io/null-sel-clr-base":"true","cpu-feature.node.kubevirt.io/nx":"true","cpu-feature.node.kubevirt.io/osvw":"true","cpu-feature.node.kubevirt.io/pae":"true","cpu-feature.node.kubevirt.io/pat":"true","cpu-feature.node.kubevirt.io/pause-filter":"true","cpu-feature.node.kubevirt.io/pcid":"true","cpu-feature.node.kubevirt.io/pclmuldq":"true","cpu-feature.node.kubevirt.io/pdpe1gb":"true","cpu-feature.node.kubevirt.io/perfctr_core":"true","cpu-feature.node.kubevirt.io/pfthreshold":"true","cpu-feature.node.kubevirt.io/pge":"true","cpu-feature.node.kubevirt.io/pku":"true","cpu-feature.node.kubevirt.io/pni":"true","cpu-feature.node.kubevirt.io/popcnt":"true","cpu-feature.node.kubevirt.io/pschange-mc-no":"true","cpu-feature.node.kubevirt.io/pse":"true","cpu-feature.node.kubevirt.io/pse36":"true","cpu-feature.node.kubevirt.io/rdctl-no":"true","cpu-feature.node.kubevirt.io/rdpid":"true","cpu-feature.node.kubevirt.io/rdrand":"true","cpu-feature.node.kubevirt.io/rdseed":"true","cpu-feature.node.kubevirt.io/rdtscp":"true","cpu-feature.node.kubevirt.io/sep":"true","cpu-feature.node.kubevirt.io/sha-ni":"true","cpu-feature.node.kubevirt.io/skip-l1dfl-vmentry":"true","cpu-feature.node.kubevirt.io/smap":"true","cpu-feature.node.kubevirt.io/smep":"true","cpu-feature.node.kubevirt.io/spec-ctrl":"true","cpu-feature.node.kubevirt.io/ssbd":"true","cpu-feature.node.kubevirt.io/sse":"true","cpu-feature.node.kubevirt.io/sse2":"true","cpu-feature.node.kubevirt.io/sse4.1":"true","cpu-feature.node.kubevirt.io/sse4.2":"true","cpu-feature.node.kubevirt.io/sse4a":"true","cpu-feature.node.kubevirt.io/ssse3":"true","cpu-feature.node.kubevirt.io/stibp":"true","cpu-feature.node.kubevirt.io/stibp-always-on":"true","cpu-feature.node.kubevirt.io/svm":"true","cpu-feature.node.kubevirt.io/svme-addr-chk":"true","cpu-feature.node.kubevirt.io/syscall":"true","cpu-feature.node.kubevirt.io/tsc":"true","cpu-feature.node.kubevirt.io/tsc-deadline":"true","cpu-feature.node.kubevirt.io/tsc-scale":"true","cpu-feature.node.kubevirt.io/tsc_adjust":"true","cpu-feature.node.kubevirt.io/umip":"true","cpu-feature.node.kubevirt.io/v-vmsave-vmload":"true","cpu-feature.node.kubevirt.io/vaes":"true","cpu-feature.node.kubevirt.io/vgif":"true","cpu-feature.node.kubevirt.io/virt-ssbd":"true","cpu-feature.node.kubevirt.io/vmcb-clean":"true","cpu-feature.node.kubevirt.io/vme":"true","cpu-feature.node.kubevirt.io/vnmi":"true","cpu-feature.node.kubevirt.io/vpclmulqdq":"true","cpu-feature.node.kubevirt.io/wbnoinvd":"true","cpu-feature.node.kubevirt.io/x2apic":"true","cpu-feature.node.kubevirt.io/xgetbv1":"true","cpu-feature.node.kubevirt.io/xsave":"true","cpu-feature.node.kubevirt.io/xsavec":"true","cpu-feature.node.kubevirt.io/xsaveerptr":"true","cpu-feature.node.kubevirt.io/xsaveopt":"true","cpu-feature.node.kubevirt.io/xsaves":"true","cpu-model-migration.node.kubevirt.io/Broadwell-noTSX":"true","cpu-model-migration.node.kubevirt.io/Broadwell-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Dhyana":"true","cpu-model-migration.node.kubevirt.io/EPYC":"true","cpu-model-migration.node.kubevirt.io/EPYC-Genoa":"true","cpu-model-migration.node.kubevirt.io/EPYC-IBPB":"true","cpu-model-migration.node.kubevirt.io/EPYC-Milan":"true","cpu-model-migration.node.kubevirt.io/EPYC-Rome":"true","cpu-model-migration.node.kubevirt.io/Haswell-noTSX":"true","cpu-model-migration.node.kubevirt.io/Haswell-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Icelake-Server-noTSX":"true","cpu-model-migration.node.kubevirt.io/IvyBridge":"true","cpu-model-migration.node.kubevirt.io/IvyBridge-IBRS":"true","cpu-model-migration.node.kubevirt.io/Nehalem":"true","cpu-model-migration.node.kubevirt.io/Nehalem-IBRS":"true","cpu-model-migration.node.kubevirt.io/Opteron_G3":"true","cpu-model-migration.node.kubevirt.io/Penryn":"true","cpu-model-migration.node.kubevirt.io/SandyBridge":"true","cpu-model-migration.node.kubevirt.io/SandyBridge-IBRS":"true","cpu-model-migration.node.kubevirt.io/Skylake-Client-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Skylake-Server-noTSX-IBRS":"true","cpu-model-migration.node.kubevirt.io/Westmere":"true","cpu-model-migration.node.kubevirt.io/Westmere-IBRS":"true","cpu-model.node.kubevirt.io/Broadwell-noTSX":"true","cpu-model.node.kubevirt.io/Broadwell-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Dhyana":"true","cpu-model.node.kubevirt.io/EPYC":"true","cpu-model.node.kubevirt.io/EPYC-Genoa":"true","cpu-model.node.kubevirt.io/EPYC-IBPB":"true","cpu-model.node.kubevirt.io/EPYC-Milan":"true","cpu-model.node.kubevirt.io/EPYC-Rome":"true","cpu-model.node.kubevirt.io/Haswell-noTSX":"true","cpu-model.node.kubevirt.io/Haswell-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Icelake-Server-noTSX":"true","cpu-model.node.kubevirt.io/IvyBridge":"true","cpu-model.node.kubevirt.io/IvyBridge-IBRS":"true","cpu-model.node.kubevirt.io/Nehalem":"true","cpu-model.node.kubevirt.io/Nehalem-IBRS":"true","cpu-model.node.kubevirt.io/Opteron_G3":"true","cpu-model.node.kubevirt.io/Penryn":"true","cpu-model.node.kubevirt.io/SandyBridge":"true","cpu-model.node.kubevirt.io/SandyBridge-IBRS":"true","cpu-model.node.kubevirt.io/Skylake-Client-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Skylake-Server-noTSX-IBRS":"true","cpu-model.node.kubevirt.io/Westmere":"true","cpu-model.node.kubevirt.io/Westmere-IBRS":"true","cpu-vendor.node.kubevirt.io/AMD":"true","cpumanager":"false","host-model-cpu.node.kubevirt.io/EPYC-Genoa":"true","host-model-required-features.node.kubevirt.io/arch-capabilities":"true","host-model-required-features.node.kubevirt.io/cmp_legacy":"true","host-model-required-features.node.kubevirt.io/flush-l1d":"true","host-model-required-features.node.kubevirt.io/gds-no":"true","host-model-required-features.node.kubevirt.io/hypervisor":"true","host-model-required-features.node.kubevirt.io/lbrv":"true","host-model-required-features.node.kubevirt.io/mds-no":"true","host-model-required-features.node.kubevirt.io/pause-filter":"true","host-model-required-features.node.kubevirt.io/pfthreshold":"true","host-model-required-features.node.kubevirt.io/pschange-mc-no":"true","host-model-required-features.node.kubevirt.io/rdctl-no":"true","host-model-required-features.node.kubevirt.io/skip-l1dfl-vmentry":"true","host-model-required-features.node.kubevirt.io/spec-ctrl":"true","host-model-required-features.node.kubevirt.io/ssbd":"true","host-model-required-features.node.kubevirt.io/stibp":"true","host-model-required-features.node.kubevirt.io/tsc-deadline":"true","host-model-required-features.node.kubevirt.io/tsc-scale":"true","host-model-required-features.node.kubevirt.io/tsc_adjust":"true","host-model-required-features.node.kubevirt.io/v-vmsave-vmload":"true","host-model-required-features.node.kubevirt.io/vgif":"true","host-model-required-features.node.kubevirt.io/virt-ssbd":"true","host-model-required-features.node.kubevirt.io/vmcb-clean":"true","host-model-required-features.node.kubevirt.io/x2apic":"true","hyperv.node.kubevirt.io/base":"true","hyperv.node.kubevirt.io/frequencies":"true","hyperv.node.kubevirt.io/ipi":"true","hyperv.node.kubevirt.io/reenlightenment":"true","hyperv.node.kubevirt.io/reset":"true","hyperv.node.kubevirt.io/runtime":"true","hyperv.node.kubevirt.io/synic":"true","hyperv.node.kubevirt.io/synic2":"true","hyperv.node.kubevirt.io/synictimer":"true","hyperv.node.kubevirt.io/time":"true","hyperv.node.kubevirt.io/tlbflush":"true","hyperv.node.kubevirt.io/vpindex":"true","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"crc","kubernetes.io/os":"linux","kubevirt.io/ksm-enabled":"false","kubevirt.io/schedulable":"true","node-role.kubernetes.io/control-plane":"","node-role.kubernetes.io/master":"","node-role.kubernetes.io/worker":"","node.openshift.io/os_id":"rhcos","topology.hostpath.csi/node":"crc"},"annotations":{"csi.volume.kubernetes.io/nodeid":"{\"kubevirt.io.hostpath-provisioner\":\"crc\"}","k8s.ovn.org/host-cidrs":"[\"192.168.126.11/24\",\"192.168.127.2/24\"]","k8s.ovn.org/l3-gateway-config":"{\"default\":{\"mode\":\"shared\",\"bridge-id\":\"br-ex\",\"interface-id\":\"br-ex_crc\",\"mac-address\":\"5a:94:ef:e4:0c:ee\",\"ip-addresses\":[\"192.168.127.2/24\"],\"ip-address\":\"192.168.127.2/24\",\"next-hops\":[\"192.168.127.1\"],\"next-hop\":\"192.168.127.1\",\"node-port-enable\":\"true\",\"vlan-id\":\"0\"}}","k8s.ovn.org/network-ids":"{\"default\":\"0\"}","k8s.ovn.org/node-chassis-id":"1d5906ba-b111-4f75-bb53-27081dee4912","k8s.ovn.org/node-gateway-router-lrp-ifaddrs":"{\"default\":{\"ipv4\":\"100.64.0.2/16\"}}","k8s.ovn.org/node-id":"2","k8s.ovn.org/node-masquerade-subnet":"{\"ipv4\":\"169.254.0.0/17\",\"ipv6\":\"fd69::/112\"}","k8s.ovn.org/node-mgmt-port-mac-addresses":"{\"default\":\"4a:d3:c4:d7:10:a4\"}","k8s.ovn.org/node-primary-ifaddr":"{\"ipv4\":\"192.168.127.2/24\"}","k8s.ovn.org/node-subnets":"{\"default\":[\"10.217.0.0/23\"]}","k8s.ovn.org/node-transit-switch-port-ifaddr":"{\"ipv4\":\"100.88.0.2/16\"}","k8s.ovn.org/remote-zone-migrated":"crc","k8s.ovn.org/zone-name":"crc","kubevirt.io/heartbeat":"2025-02-26T19:04:51Z","kubevirt.io/ksm-handler-managed":"false","machineconfiguration.openshift.io/controlPlaneTopology":"SingleReplica","machineconfiguration.openshift.io/currentConfig":"rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/desiredConfig":"rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/desiredDrain":"uncordon-rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/lastAppliedDrain":"uncordon-rendered-master-b8ab559a77bb8886ad4aea23e23460f5","machineconfiguration.openshift.io/lastObservedServerCAAnnotation":"false","machineconfiguration.openshift.io/lastSyncedControllerConfigResourceVersion":"1103865","machineconfiguration.openshift.io/post-config-action":"","machineconfiguration.openshift.io/reason":"","machineconfiguration.openshift.io/state":"Done","volumes.kubernetes.io/controller-managed-attach-detach":"true"},"managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2025-02-09T10:30:38Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:volumes.kubernetes.io/controller-managed-attach-detach":{}},"f:labels":{".":{},"f:beta.kubernetes.io/arch":{},"f:beta.kubernetes.io/os":{},"f:kubernetes.io/arch":{},"f:kubernetes.io/hostname":{},"f:kubernetes.io/os":{},"f:node-role.kubernetes.io/control-plane":{},"f:node-role.kubernetes.io/master":{},"f:node.openshift.io/os_id":{}}}}},{"manager":"crc","operation":"Update","apiVersion":"v1","time":"2025-02-24T20:22:03Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:k8s.ovn.org/host-cidrs":{},"f:k8s.ovn.org/l3-gateway-config":{},"f:k8s.ovn.org/network-ids":{},"f:k8s.ovn.org/node-chassis-id":{},"f:k8s.ovn.org/node-gateway-router-lrp-ifaddrs":{},"f:k8s.ovn.org/node-id":{},"f:k8s.ovn.org/node-masquerade-subnet":{},"f:k8s.ovn.org/node-mgmt-port-mac-addresses":{},"f:k8s.ovn.org/node-primary-ifaddr":{},"f:k8s.ovn.org/node-subnets":{},"f:k8s.ovn.org/node-transit-switch-port-ifaddr":{},"f:k8s.ovn.org/remote-zone-migrated":{},"f:k8s.ovn.org/zone-name":{}}}},"subresource":"status"},{"manager":"machine-config-controller","operation":"Update","apiVersion":"v1","time":"2025-02-24T20:23:27Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:machineconfiguration.openshift.io/controlPlaneTopology":{},"f:machineconfiguration.openshift.io/desiredConfig":{},"f:machineconfiguration.openshift.io/lastAppliedDrain":{}},"f:labels":{"f:node-role.kubernetes.io/worker":{}}}}},{"manager":"machine-config-daemon","operation":"Update","apiVersion":"v1","time":"2025-02-26T18:36:35Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:machineconfiguration.openshift.io/currentConfig":{},"f:machineconfiguration.openshift.io/desiredDrain":{},"f:machineconfiguration.openshift.io/lastObservedServerCAAnnotation":{},"f:machineconfiguration.openshift.io/lastSyncedControllerConfigResourceVersion":{},"f:machineconfiguration.openshift.io/post-config-action":{},"f:machineconfiguration.openshift.io/reason":{},"f:machineconfiguration.openshift.io/state":{}}}}},{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2025-02-26T19:01:56Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:csi.volume.kubernetes.io/nodeid":{}},"f:labels":{"f:topology.hostpath.csi/node":{}}},"f:status":{"f:allocatable":{"f:cpu":{},"f:devices.kubevirt.io/kvm":{},"f:devices.kubevirt.io/tun":{},"f:devices.kubevirt.io/vhost-net":{},"f:ephemeral-storage":{},"f:memory":{}},"f:capacity":{"f:cpu":{},"f:devices.kubevirt.io/kvm":{},"f:devices.kubevirt.io/tun":{},"f:devices.kubevirt.io/vhost-net":{},"f:ephemeral-storage":{},"f:memory":{}},"f:conditions":{"k:{\"type\":\"DiskPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"MemoryPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"PIDPressure\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}},"k:{\"type\":\"Ready\"}":{"f:lastHeartbeatTime":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{}}},"f:images":{},"f:nodeInfo":{"f:bootID":{},"f:systemUUID":{}}}},"subresource":"status"},{"manager":"virt-handler","operation":"Update","apiVersion":"v1","time":"2025-02-26T19:04:51Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:kubevirt.io/heartbeat":{},"f:kubevirt.io/ksm-handler-managed":{}},"f:labels":{"f:cpu-feature.node.kubevirt.io/3dnowprefetch":{},"f:cpu-feature.node.kubevirt.io/abm":{},"f:cpu-feature.node.kubevirt.io/adx":{},"f:cpu-feature.node.kubevirt.io/aes":{},"f:cpu-feature.node.kubevirt.io/amd-psfd":{},"f:cpu-feature.node.kubevirt.io/amd-ssbd":{},"f:cpu-feature.node.kubevirt.io/amd-stibp":{},"f:cpu-feature.node.kubevirt.io/apic":{},"f:cpu-feature.node.kubevirt.io/arat":{},"f:cpu-feature.node.kubevirt.io/arch-capabilities":{},"f:cpu-feature.node.kubevirt.io/auto-ibrs":{},"f:cpu-feature.node.kubevirt.io/avx":{},"f:cpu-feature.node.kubevirt.io/avx2":{},"f:cpu-feature.node.kubevirt.io/avx512-bf16":{},"f:cpu-feature.node.kubevirt.io/avx512-vpopcntdq":{},"f:cpu-feature.node.kubevirt.io/avx512bitalg":{},"f:cpu-feature.node.kubevirt.io/avx512bw":{},"f:cpu-feature.node.kubevirt.io/avx512cd":{},"f:cpu-feature.node.kubevirt.io/avx512dq":{},"f:cpu-feature.node.kubevirt.io/avx512f":{},"f:cpu-feature.node.kubevirt.io/avx512ifma":{},"f:cpu-feature.node.kubevirt.io/avx512vbmi":{},"f:cpu-feature.node.kubevirt.io/avx512vbmi2":{},"f:cpu-feature.node.kubevirt.io/avx512vl":{},"f:cpu-feature.node.kubevirt.io/avx512vnni":{},"f:cpu-feature.node.kubevirt.io/bmi1":{},"f:cpu-feature.node.kubevirt.io/bmi2":{},"f:cpu-feature.node.kubevirt.io/clflush":{},"f:cpu-feature.node.kubevirt.io/clflushopt":{},"f:cpu-feature.node.kubevirt.io/clwb":{},"f:cpu-feature.node.kubevirt.io/clzero":{},"f:cpu-feature.node.kubevirt.io/cmov":{},"f:cpu-feature.node.kubevirt.io/cmp_legacy":{},"f:cpu-feature.node.kubevirt.io/cr8legacy":{},"f:cpu-feature.node.kubevirt.io/cx16":{},"f:cpu-feature.node.kubevirt.io/cx8":{},"f:cpu-feature.node.kubevirt.io/de":{},"f:cpu-feature.node.kubevirt.io/erms":{},"f:cpu-feature.node.kubevirt.io/f16c":{},"f:cpu-feature.node.kubevirt.io/flush-l1d":{},"f:cpu-feature.node.kubevirt.io/fma":{},"f:cpu-feature.node.kubevirt.io/fpu":{},"f:cpu-feature.node.kubevirt.io/fsgsbase":{},"f:cpu-feature.node.kubevirt.io/fsrm":{},"f:cpu-feature.node.kubevirt.io/fxsr":{},"f:cpu-feature.node.kubevirt.io/fxsr_opt":{},"f:cpu-feature.node.kubevirt.io/gds-no":{},"f:cpu-feature.node.kubevirt.io/gfni":{},"f:cpu-feature.node.kubevirt.io/hypervisor":{},"f:cpu-feature.node.kubevirt.io/ibpb":{},"f:cpu-feature.node.kubevirt.io/ibrs":{},"f:cpu-feature.node.kubevirt.io/invpcid":{},"f:cpu-feature.node.kubevirt.io/la57":{},"f:cpu-feature.node.kubevirt.io/lahf_lm":{},"f:cpu-feature.node.kubevirt.io/lbrv":{},"f:cpu-feature.node.kubevirt.io/lfence-always-serializing":{},"f:cpu-feature.node.kubevirt.io/lm":{},"f:cpu-feature.node.kubevirt.io/mca":{},"f:cpu-feature.node.kubevirt.io/mce":{},"f:cpu-feature.node.kubevirt.io/mds-no":{},"f:cpu-feature.node.kubevirt.io/misalignsse":{},"f:cpu-feature.node.kubevirt.io/mmx":{},"f:cpu-feature.node.kubevirt.io/mmxext":{},"f:cpu-feature.node.kubevirt.io/movbe":{},"f:cpu-feature.node.kubevirt.io/msr":{},"f:cpu-feature.node.kubevirt.io/mtrr":{},"f:cpu-feature.node.kubevirt.io/no-nested-data-bp":{},"f:cpu-feature.node.kubevirt.io/npt":{},"f:cpu-feature.node.kubevirt.io/nrip-save":{},"f:cpu-feature.node.kubevirt.io/null-sel-clr-base":{},"f:cpu-feature.node.kubevirt.io/nx":{},"f:cpu-feature.node.kubevirt.io/osvw":{},"f:cpu-feature.node.kubevirt.io/pae":{},"f:cpu-feature.node.kubevirt.io/pat":{},"f:cpu-feature.node.kubevirt.io/pause-filter":{},"f:cpu-feature.node.kubevirt.io/pcid":{},"f:cpu-feature.node.kubevirt.io/pclmuldq":{},"f:cpu-feature.node.kubevirt.io/pdpe1gb":{},"f:cpu-feature.node.kubevirt.io/perfctr_core":{},"f:cpu-feature.node.kubevirt.io/pfthreshold":{},"f:cpu-feature.node.kubevirt.io/pge":{},"f:cpu-feature.node.kubevirt.io/pku":{},"f:cpu-feature.node.kubevirt.io/pni":{},"f:cpu-feature.node.kubevirt.io/popcnt":{},"f:cpu-feature.node.kubevirt.io/pschange-mc-no":{},"f:cpu-feature.node.kubevirt.io/pse":{},"f:cpu-feature.node.kubevirt.io/pse36":{},"f:cpu-feature.node.kubevirt.io/rdctl-no":{},"f:cpu-feature.node.kubevirt.io/rdpid":{},"f:cpu-feature.node.kubevirt.io/rdrand":{},"f:cpu-feature.node.kubevirt.io/rdseed":{},"f:cpu-feature.node.kubevirt.io/rdtscp":{},"f:cpu-feature.node.kubevirt.io/sep":{},"f:cpu-feature.node.kubevirt.io/sha-ni":{},"f:cpu-feature.node.kubevirt.io/skip-l1dfl-vmentry":{},"f:cpu-feature.node.kubevirt.io/smap":{},"f:cpu-feature.node.kubevirt.io/smep":{},"f:cpu-feature.node.kubevirt.io/spec-ctrl":{},"f:cpu-feature.node.kubevirt.io/ssbd":{},"f:cpu-feature.node.kubevirt.io/sse":{},"f:cpu-feature.node.kubevirt.io/sse2":{},"f:cpu-feature.node.kubevirt.io/sse4.1":{},"f:cpu-feature.node.kubevirt.io/sse4.2":{},"f:cpu-feature.node.kubevirt.io/sse4a":{},"f:cpu-feature.node.kubevirt.io/ssse3":{},"f:cpu-feature.node.kubevirt.io/stibp":{},"f:cpu-feature.node.kubevirt.io/stibp-always-on":{},"f:cpu-feature.node.kubevirt.io/svm":{},"f:cpu-feature.node.kubevirt.io/svme-addr-chk":{},"f:cpu-feature.node.kubevirt.io/syscall":{},"f:cpu-feature.node.kubevirt.io/tsc":{},"f:cpu-feature.node.kubevirt.io/tsc-deadline":{},"f:cpu-feature.node.kubevirt.io/tsc-scale":{},"f:cpu-feature.node.kubevirt.io/tsc_adjust":{},"f:cpu-feature.node.kubevirt.io/umip":{},"f:cpu-feature.node.kubevirt.io/v-vmsave-vmload":{},"f:cpu-feature.node.kubevirt.io/vaes":{},"f:cpu-feature.node.kubevirt.io/vgif":{},"f:cpu-feature.node.kubevirt.io/virt-ssbd":{},"f:cpu-feature.node.kubevirt.io/vmcb-clean":{},"f:cpu-feature.node.kubevirt.io/vme":{},"f:cpu-feature.node.kubevirt.io/vnmi":{},"f:cpu-feature.node.kubevirt.io/vpclmulqdq":{},"f:cpu-feature.node.kubevirt.io/wbnoinvd":{},"f:cpu-feature.node.kubevirt.io/x2apic":{},"f:cpu-feature.node.kubevirt.io/xgetbv1":{},"f:cpu-feature.node.kubevirt.io/xsave":{},"f:cpu-feature.node.kubevirt.io/xsavec":{},"f:cpu-feature.node.kubevirt.io/xsaveerptr":{},"f:cpu-feature.node.kubevirt.io/xsaveopt":{},"f:cpu-feature.node.kubevirt.io/xsaves":{},"f:cpu-model-migration.node.kubevirt.io/Broadwell-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/Broadwell-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Dhyana":{},"f:cpu-model-migration.node.kubevirt.io/EPYC":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Genoa":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-IBPB":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Milan":{},"f:cpu-model-migration.node.kubevirt.io/EPYC-Rome":{},"f:cpu-model-migration.node.kubevirt.io/Haswell-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/Haswell-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Icelake-Server-noTSX":{},"f:cpu-model-migration.node.kubevirt.io/IvyBridge":{},"f:cpu-model-migration.node.kubevirt.io/IvyBridge-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Nehalem":{},"f:cpu-model-migration.node.kubevirt.io/Nehalem-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Opteron_G3":{},"f:cpu-model-migration.node.kubevirt.io/Penryn":{},"f:cpu-model-migration.node.kubevirt.io/SandyBridge":{},"f:cpu-model-migration.node.kubevirt.io/SandyBridge-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Skylake-Client-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Skylake-Server-noTSX-IBRS":{},"f:cpu-model-migration.node.kubevirt.io/Westmere":{},"f:cpu-model-migration.node.kubevirt.io/Westmere-IBRS":{},"f:cpu-model.node.kubevirt.io/Broadwell-noTSX":{},"f:cpu-model.node.kubevirt.io/Broadwell-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Dhyana":{},"f:cpu-model.node.kubevirt.io/EPYC":{},"f:cpu-model.node.kubevirt.io/EPYC-Genoa":{},"f:cpu-model.node.kubevirt.io/EPYC-IBPB":{},"f:cpu-model.node.kubevirt.io/EPYC-Milan":{},"f:cpu-model.node.kubevirt.io/EPYC-Rome":{},"f:cpu-model.node.kubevirt.io/Haswell-noTSX":{},"f:cpu-model.node.kubevirt.io/Haswell-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Icelake-Server-noTSX":{},"f:cpu-model.node.kubevirt.io/IvyBridge":{},"f:cpu-model.node.kubevirt.io/IvyBridge-IBRS":{},"f:cpu-model.node.kubevirt.io/Nehalem":{},"f:cpu-model.node.kubevirt.io/Nehalem-IBRS":{},"f:cpu-model.node.kubevirt.io/Opteron_G3":{},"f:cpu-model.node.kubevirt.io/Penryn":{},"f:cpu-model.node.kubevirt.io/SandyBridge":{},"f:cpu-model.node.kubevirt.io/SandyBridge-IBRS":{},"f:cpu-model.node.kubevirt.io/Skylake-Client-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Skylake-Server-noTSX-IBRS":{},"f:cpu-model.node.kubevirt.io/Westmere":{},"f:cpu-model.node.kubevirt.io/Westmere-IBRS":{},"f:cpu-vendor.node.kubevirt.io/AMD":{},"f:cpumanager":{},"f:host-model-cpu.node.kubevirt.io/EPYC-Genoa":{},"f:host-model-required-features.node.kubevirt.io/arch-capabilities":{},"f:host-model-required-features.node.kubevirt.io/cmp_legacy":{},"f:host-model-required-features.node.kubevirt.io/flush-l1d":{},"f:host-model-required-features.node.kubevirt.io/gds-no":{},"f:host-model-required-features.node.kubevirt.io/hypervisor":{},"f:host-model-required-features.node.kubevirt.io/lbrv":{},"f:host-model-required-features.node.kubevirt.io/mds-no":{},"f:host-model-required-features.node.kubevirt.io/pause-filter":{},"f:host-model-required-features.node.kubevirt.io/pfthreshold":{},"f:host-model-required-features.node.kubevirt.io/pschange-mc-no":{},"f:host-model-required-features.node.kubevirt.io/rdctl-no":{},"f:host-model-required-features.node.kubevirt.io/skip-l1dfl-vmentry":{},"f:host-model-required-features.node.kubevirt.io/spec-ctrl":{},"f:host-model-required-features.node.kubevirt.io/ssbd":{},"f:host-model-required-features.node.kubevirt.io/stibp":{},"f:host-model-required-features.node.kubevirt.io/tsc-deadline":{},"f:host-model-required-features.node.kubevirt.io/tsc-scale":{},"f:host-model-required-features.node.kubevirt.io/tsc_adjust":{},"f:host-model-required-features.node.kubevirt.io/v-vmsave-vmload":{},"f:host-model-required-features.node.kubevirt.io/vgif":{},"f:host-model-required-features.node.kubevirt.io/virt-ssbd":{},"f:host-model-required-features.node.kubevirt.io/vmcb-clean":{},"f:host-model-required-features.node.kubevirt.io/x2apic":{},"f:hyperv.node.kubevirt.io/base":{},"f:hyperv.node.kubevirt.io/frequencies":{},"f:hyperv.node.kubevirt.io/ipi":{},"f:hyperv.node.kubevirt.io/reenlightenment":{},"f:hyperv.node.kubevirt.io/reset":{},"f:hyperv.node.kubevirt.io/runtime":{},"f:hyperv.node.kubevirt.io/synic":{},"f:hyperv.node.kubevirt.io/synic2":{},"f:hyperv.node.kubevirt.io/synictimer":{},"f:hyperv.node.kubevirt.io/time":{},"f:hyperv.node.kubevirt.io/tlbflush":{},"f:hyperv.node.kubevirt.io/vpindex":{},"f:kubevirt.io/ksm-enabled":{},"f:kubevirt.io/schedulable":{}}}}}]},"spec":{},"status":{"capacity":{"cpu":"8","devices.kubevirt.io/kvm":"1k","devices.kubevirt.io/tun":"1k","devices.kubevirt.io/vhost-net":"1k","ephemeral-storage":"133626860Ki","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"24600668Ki","pods":"250"},"allocatable":{"cpu":"7800m","devices.kubevirt.io/kvm":"1k","devices.kubevirt.io/tun":"1k","devices.kubevirt.io/vhost-net":"1k","ephemeral-storage":"122783512373","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"24139868Ki","pods":"250"},"conditions":[{"type":"MemoryPressure","status":"False","lastHeartbeatTime":"2025-02-26T19:01:56Z","lastTransitionTime":"2025-02-24T20:22:04Z","reason":"KubeletHasSufficientMemory","message":"kubelet
         has sufficient memory available"},{"type":"DiskPressure","status":"False","lastHeartbeatTime":"2025-02-26T19:01:56Z","lastTransitionTime":"2025-02-24T20:22:04Z","reason":"KubeletHasNoDiskPressure","message":"kubelet
         has no disk pressure"},{"type":"PIDPressure","status":"False","lastHeartbeatTime":"2025-02-26T19:01:56Z","lastTransitionTime":"2025-02-24T20:22:04Z","reason":"KubeletHasSufficientPID","message":"kubelet
         has sufficient PID available"},{"type":"Ready","status":"True","lastHeartbeatTime":"2025-02-26T19:01:56Z","lastTransitionTime":"2025-02-26T12:36:17Z","reason":"KubeletReady","message":"kubelet
@@ -130,49 +88,7 @@ http_interactions:
         Hat Enterprise Linux CoreOS 417.94.202501220426-0","containerRuntimeVersion":"cri-o://1.30.9-3.rhaos4.17.gitbbf9018.el9","kubeletVersion":"v1.30.7","kubeProxyVersion":"v1.30.7","operatingSystem":"linux","architecture":"amd64"},"images":[{"names":["quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:77b4d706322aa2b3f987449004df4c9be55697bc4140728148ca26efe717016f"],"sizeBytes":2657675543},{"names":["quay.io/containerdisks/centos-stream@sha256:45036e2a965a75a6ec6fe5ac76efece99382a7df6ea0d8b3bd66acdbefb47324","quay.io/containerdisks/centos-stream@sha256:f7720aa1f60d0876f9514ac294dff07e2d45b5a5f475b6b7c5934d573ebd7080"],"sizeBytes":2003702612},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:8bb473d6f044d0b1554d70c80e707fc05422b610d8a93e5ed23cfd898e986148","registry.redhat.io/redhat/redhat-operator-index@sha256:b970aa38187429c28e45156e1068b5cf2fe058ee0e1544a0e0741f3cc87e2d20","registry.redhat.io/redhat/redhat-operator-index:v4.17"],"sizeBytes":1603806598},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:0fa4b4367f9762e9209e5f56b886d7c3212cd9aa50d5e1af27c1bad7a203e079"],"sizeBytes":1603267457},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:b7d9829689e50d7362fb25ce2ad6fb4a9525eb902b78249eac5de2b081bc63b4"],"sizeBytes":1602197347},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:0af2e7273894cbd935e0aa2da588e47467736b203083ff184ad4940c6f9c547f"],"sizeBytes":1600251275},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:da39f2c315e452444a4c3e03bc1d7a3202e4f411a255918749a8bc5a57051ab9"],"sizeBytes":1599746447},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:66046ab6182a200266b92713f2e0257bf4f921ac893ad6b5f601375a4ced139e"],"sizeBytes":1599724191},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:0f38bbc00442d1bd032b184aaf44c2d32f9273d59ec86225ceac1f24d2dedc64"],"sizeBytes":1599637385},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:df3dfc184c9477d07cecba388b87cd85b1c103e7e4c668163af4ae65f5ffd9ed"],"sizeBytes":1599446689},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:01fa1e5c4d184424a4931cd8397baa549be4b78f088b94aa400ae73eebf4b1f2"],"sizeBytes":1596576641},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:7e43345c8856d7a965a1470940ffdde301c8554935a31d7c28bfcde3f0c0dec9"],"sizeBytes":1595022224},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:1c4a3af1c23baecac0f8375af3c1be53c01bd7912556e1d61ee0699e2ce14ee9"],"sizeBytes":1593944951},{"names":["registry.redhat.io/redhat/redhat-operator-index@sha256:db83ac3d150e7f87eb7ebbb040c84fb88c4d01ac656730b643f63e0e078cfa50"],"sizeBytes":1565810261},{"names":["quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:d215bff03d287b215b7a423377b0cd01cd9170675c3bb2d70948e2a7a9e1ccb1"],"sizeBytes":1377800515},{"names":["quay.io/containerdisks/centos-stream@sha256:7c6542eff2d2dcf08945355d9bbf2ab57dfbdb3e91edd07d8a4769935d1d8640","quay.io/containerdisks/centos-stream@sha256:cca37e76181d85772cf09c17ad9e7e9f2d58a5b3fcfaeee85fa0d559b09c7912"],"sizeBytes":1263924776},{"names":["quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:58522bba37b0b3bb9a0103e8d7f99a85042840d58f49dd847d206e0c2159472b"],"sizeBytes":1232786685},{"names":["quay.io/containerdisks/centos-stream@sha256:c10d39f4f6cb9a7865d49f3407835e1ac7b20a7481dafd780b449f31035a0a9b","quay.io/containerdisks/centos-stream@sha256:c1f8429913f39492c5d79ebf079b594454a0f91afa2288dd8ada92f3a4b06ce3"],"sizeBytes":1224609832},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:4d38805ce569a2a4e47a886a44c3c964ab072f8bc031cdc3545d47822f0b0c0b"],"sizeBytes":1162191542},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:301f960951cd3485a2d1534f6a129f71d7d54000b3254cb00c4658fe29e1b6ef","registry.redhat.io/redhat/community-operator-index@sha256:d3352254a06b3b15d27fc7d3ecd2400befd5f58b02e28475c9c8b98ddc52f98b","registry.redhat.io/redhat/community-operator-index:v4.17"],"sizeBytes":1162099886},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:d18c2a6c45317700810f9ff2692ffaa29e9230a4907b3aabd0d06d73d94c6d4a"],"sizeBytes":1162085032},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:2c314c8b9dc3d66c423bf4e9f195c9f2aa6004205f10bf84d6efe33def42fdab"],"sizeBytes":1162022067},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:1b0e3a118761d30306960dc456e64d8e714eeadd386e992d76fd5f55bac99394"],"sizeBytes":1162002608},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:300af6b453b89381dfa4c37a22883f9845e0e098f1403bf085d8758232467e1d"],"sizeBytes":1161980589},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:9b6e81590db43d171c2f421ca70dacadb03459634d6ad0fc0da2f1a70d123fbf"],"sizeBytes":1161958062},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:eb6a793b5ed53d00fd709209272e2be9577f49b772cd89ab8931943142aea6ae"],"sizeBytes":1161937584},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:08a03ce8c51b726c8b98f126628843c5f409a7d5562e3128c5a95b96e63e849d"],"sizeBytes":1161934513},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:1897952e1fe9ce4e39b98700777dc2ec384ba9a738ebfb55f766516173143de0"],"sizeBytes":1161925811},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:769d2604b045e6586391eb46b1a466ba87307c1ce082b1c30e6261035ca45507"],"sizeBytes":1161911482},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:76cb2bf13ef7b42d71233f059824d123c0c21c4c0211e7afe33f0fe23a281c98"],"sizeBytes":1161897139},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:7b126d6ba287b403f206228bd4cbea5d0b07f1a0bdfa9f5d0aef02cdb0523a46"],"sizeBytes":1161889463},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:de30f34d1e14ae82a26715773aefacf79f2169b607e547061bf873b45bc853d8"],"sizeBytes":1161866935},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:524c4d49ad06e6823ec808b4c5e9b7206da77c2a1668e5c2c0a3e8e0fd484ada"],"sizeBytes":1161842354},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:a73e9d1674e1f133257935546f087be8ef3cfa6ddab2c8593fa7e7d52eb212cb"],"sizeBytes":1161839279},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:ec17c76409e7a59590eee9cbf505b3677f14b498b47a7ecaa7de18243f40e1d2"],"sizeBytes":1161836204},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:16064d58bdb205c91456c39d972915382cc4124885db33d1aaa9b4282e529686"],"sizeBytes":1161819817},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:5610173b93bfd031e2cad81ffc816a5b37764dd9d8f79c58850180d1425dfff9"],"sizeBytes":1161797808},{"names":["registry.redhat.io/redhat/community-operator-index@sha256:604d494c558a4f210031713971f86ca0847ec74404bc94cec8317707dfe42516"],"sizeBytes":1157117827},{"names":["registry.redhat.io/rhel8/rhel-guest-image@sha256:f009c88dc243b6feb6fd9101594d3e7cf64d89cb98b5a350b5de1d16cf7a7e3d"],"sizeBytes":1140550367},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:12864dc7c55869f723b777d2826adcd2bf7e878a2ba78c1144bca57c7e4787fa"],"sizeBytes":1070170802},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:bcd9a9b31638c36e7718d5e9a23eedc9f498a7b54bfff14bdc3862ff8eac1074"],"sizeBytes":1069961905},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:95462bbcd284671887f2e83d233a684b41567d476f8258acf06780993f7ecfd4"],"sizeBytes":1069810356},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:8435066ec61aedb515961607409d931e2eee848b66da9cfb449bc2106eef077b"],"sizeBytes":1069665975},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:e217eb1b38d00c7f168e1c43b53f6017f1a63a8b312346ff914e30873fa02245"],"sizeBytes":1069533365},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:d0d138d4637a0dedfe9c21890d820f7758887f2769ce9f9480f89f50773fa856"],"sizeBytes":1067243692},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:75925b82cbac4b1a703c22fdb3f7461e42147f6091e23f391ba8770b6d3791c2"],"sizeBytes":1066884786},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:af21dfea5426aa3d3cfb751345eae21a653989bf4d69b3e58a2ec659584bd08d"],"sizeBytes":1066478769},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:53e8f2f85d538c96fbaf5e073121b176cfe0133a3938386cb2753881d4e75f86","registry.redhat.io/redhat/certified-operator-index@sha256:d889c2299ef1f1cdeb35b6ecd89c68206863608759f1fa32d0b3136189351b00","registry.redhat.io/redhat/certified-operator-index:v4.17"],"sizeBytes":1066289330},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:035fa9013b5fd6e58e2cd23607b09d09b01fe655885d44f718de2ae401f6a5c7"],"sizeBytes":1066191031},{"names":["registry.redhat.io/redhat/certified-operator-index@sha256:7293c9d48a0ea060f7f5782d30fe9151f4e202849c81c232a7afe78551905b75"],"sizeBytes":1066040970}]}}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
-- request:
-    method: get
-    uri: https://host.example.com:8443/apis/kubevirt.io
-    body:
-      encoding: US-ASCII
-      string: ''
-    headers:
-      Accept:
-      - "*/*"
-      User-Agent:
-      - rest-client/2.1.0 (linux-gnu x86_64) ruby/3.3.7p123
-      Authorization:
-      - Bearer theToken
-      Accept-Encoding:
-      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
-  response:
-    status:
-      code: 200
-      message: OK
-    headers:
-      Audit-Id:
-      - 1c8dac42-0faa-40de-9cea-4a8814e89718
-      Cache-Control:
-      - no-cache, private
-      Content-Type:
-      - application/json
-      Strict-Transport-Security:
-      - max-age=31536000; includeSubDomains; preload
-      X-Kubernetes-Pf-Flowschema-Uid:
-      - 1deef9d8-0e80-4942-b8f4-7f15731ec1ac
-      X-Kubernetes-Pf-Prioritylevel-Uid:
-      - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
-      Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
-      Content-Length:
-      - '250'
-    body:
-      encoding: UTF-8
-      string: '{"kind":"APIGroup","apiVersion":"v1","name":"kubevirt.io","versions":[{"groupVersion":"kubevirt.io/v1","version":"v1"},{"groupVersion":"kubevirt.io/v1alpha3","version":"v1alpha3"}],"preferredVersion":{"groupVersion":"kubevirt.io/v1","version":"v1"}}
-
-        '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/apis/kubevirt.io/v1
@@ -194,7 +110,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - 67856f38-10c3-4558-afae-5a428b29ea39
+      - 7090ec07-6a37-4c7a-9fbc-9852ba9fa3e2
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -206,15 +122,15 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Transfer-Encoding:
       - chunked
     body:
       encoding: UTF-8
-      string: '{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"kubevirt.io/v1","resources":[{"name":"virtualmachineinstancereplicasets","singularName":"virtualmachineinstancereplicaset","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmirs","vmirss"],"categories":["all"],"storageVersionHash":"VyiLSe/5A2Q="},{"name":"virtualmachineinstancereplicasets/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["get","patch","update"]},{"name":"virtualmachineinstancereplicasets/scale","singularName":"","namespaced":true,"group":"autoscaling","version":"v1","kind":"Scale","verbs":["get","patch","update"]},{"name":"kubevirts","singularName":"kubevirt","namespaced":true,"kind":"KubeVirt","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["kv","kvs"],"categories":["all"],"storageVersionHash":"+s0w/mxiw14="},{"name":"kubevirts/status","singularName":"","namespaced":true,"kind":"KubeVirt","verbs":["get","patch","update"]},{"name":"virtualmachines","singularName":"virtualmachine","namespaced":true,"kind":"VirtualMachine","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vm","vms"],"categories":["all"],"storageVersionHash":"v2rohjOGqcY="},{"name":"virtualmachines/status","singularName":"","namespaced":true,"kind":"VirtualMachine","verbs":["get","patch","update"]},{"name":"virtualmachineinstancemigrations","singularName":"virtualmachineinstancemigration","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmim","vmims"],"categories":["all"],"storageVersionHash":"ByphcRAtdtg="},{"name":"virtualmachineinstancemigrations/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["get","patch","update"]},{"name":"virtualmachineinstancepresets","singularName":"virtualmachineinstancepreset","namespaced":true,"kind":"VirtualMachineInstancePreset","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmipreset","vmipresets"],"categories":["all"],"storageVersionHash":"oZZyVoiG8GU="},{"name":"virtualmachineinstances","singularName":"virtualmachineinstance","namespaced":true,"kind":"VirtualMachineInstance","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmi","vmis"],"categories":["all"],"storageVersionHash":"1DClFQM6+os="}]}
+      string: '{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"kubevirt.io/v1","resources":[{"name":"virtualmachineinstances","singularName":"virtualmachineinstance","namespaced":true,"kind":"VirtualMachineInstance","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmi","vmis"],"categories":["all"],"storageVersionHash":"1DClFQM6+os="},{"name":"virtualmachineinstancereplicasets","singularName":"virtualmachineinstancereplicaset","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmirs","vmirss"],"categories":["all"],"storageVersionHash":"VyiLSe/5A2Q="},{"name":"virtualmachineinstancereplicasets/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["get","patch","update"]},{"name":"virtualmachineinstancereplicasets/scale","singularName":"","namespaced":true,"group":"autoscaling","version":"v1","kind":"Scale","verbs":["get","patch","update"]},{"name":"kubevirts","singularName":"kubevirt","namespaced":true,"kind":"KubeVirt","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["kv","kvs"],"categories":["all"],"storageVersionHash":"+s0w/mxiw14="},{"name":"kubevirts/status","singularName":"","namespaced":true,"kind":"KubeVirt","verbs":["get","patch","update"]},{"name":"virtualmachines","singularName":"virtualmachine","namespaced":true,"kind":"VirtualMachine","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vm","vms"],"categories":["all"],"storageVersionHash":"v2rohjOGqcY="},{"name":"virtualmachines/status","singularName":"","namespaced":true,"kind":"VirtualMachine","verbs":["get","patch","update"]},{"name":"virtualmachineinstancemigrations","singularName":"virtualmachineinstancemigration","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmim","vmims"],"categories":["all"],"storageVersionHash":"ByphcRAtdtg="},{"name":"virtualmachineinstancemigrations/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["get","patch","update"]},{"name":"virtualmachineinstancepresets","singularName":"virtualmachineinstancepreset","namespaced":true,"kind":"VirtualMachineInstancePreset","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmipreset","vmipresets"],"categories":["all"],"storageVersionHash":"oZZyVoiG8GU="}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/apis/kubevirt.io/v1/virtualmachines
@@ -236,7 +152,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - f00ed719-8f9a-4052-92f9-b9b3014b4368
+      - ca0b4b07-f1b3-4c38-8566-0909b2607160
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -248,7 +164,7 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Transfer-Encoding:
       - chunked
     body:
@@ -263,13 +179,13 @@ http_interactions:
         requires that all PVCs must be shared (using ReadWriteMany access mode)","reason":"DisksNotLiveMigratable","status":"False","type":"LiveMigratable"},{"lastProbeTime":"2025-02-26T18:45:45Z","lastTransitionTime":null,"status":"True","type":"AgentConnected"}],"created":true,"desiredGeneration":1,"observedGeneration":1,"printableStatus":"Running","ready":true,"runStrategy":"Always","volumeSnapshotStatuses":[{"enabled":false,"name":"rootdisk","reason":"No
         VolumeSnapshotClass: Volume snapshots are not configured for this StorageClass
         [crc-csi-hostpath-provisioner] [rootdisk]"},{"enabled":false,"name":"cloudinitdisk","reason":"Snapshot
-        is not supported for this volumeSource type [cloudinitdisk]"}]}}],"kind":"VirtualMachineList","metadata":{"continue":"","resourceVersion":"1115115"}}
+        is not supported for this volumeSource type [cloudinitdisk]"}]}}],"kind":"VirtualMachineList","metadata":{"continue":"","resourceVersion":"1115930"}}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
-    uri: https://host.example.com:8443/apis/kubevirt.io
+    uri: https://host.example.com:8443/apis/kubevirt.io/v1
     body:
       encoding: US-ASCII
       string: ''
@@ -288,7 +204,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - 7118c176-65a4-46dd-9b8a-7ff82392cff2
+      - b19632c3-9169-4439-a962-f84a76d320db
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -300,15 +216,15 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
-      Content-Length:
-      - '250'
+      - Wed, 26 Feb 2025 19:06:32 GMT
+      Transfer-Encoding:
+      - chunked
     body:
       encoding: UTF-8
-      string: '{"kind":"APIGroup","apiVersion":"v1","name":"kubevirt.io","versions":[{"groupVersion":"kubevirt.io/v1","version":"v1"},{"groupVersion":"kubevirt.io/v1alpha3","version":"v1alpha3"}],"preferredVersion":{"groupVersion":"kubevirt.io/v1","version":"v1"}}
+      string: '{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"kubevirt.io/v1","resources":[{"name":"virtualmachineinstances","singularName":"virtualmachineinstance","namespaced":true,"kind":"VirtualMachineInstance","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmi","vmis"],"categories":["all"],"storageVersionHash":"1DClFQM6+os="},{"name":"virtualmachineinstancereplicasets","singularName":"virtualmachineinstancereplicaset","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmirs","vmirss"],"categories":["all"],"storageVersionHash":"VyiLSe/5A2Q="},{"name":"virtualmachineinstancereplicasets/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceReplicaSet","verbs":["get","patch","update"]},{"name":"virtualmachineinstancereplicasets/scale","singularName":"","namespaced":true,"group":"autoscaling","version":"v1","kind":"Scale","verbs":["get","patch","update"]},{"name":"kubevirts","singularName":"kubevirt","namespaced":true,"kind":"KubeVirt","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["kv","kvs"],"categories":["all"],"storageVersionHash":"+s0w/mxiw14="},{"name":"kubevirts/status","singularName":"","namespaced":true,"kind":"KubeVirt","verbs":["get","patch","update"]},{"name":"virtualmachines","singularName":"virtualmachine","namespaced":true,"kind":"VirtualMachine","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vm","vms"],"categories":["all"],"storageVersionHash":"v2rohjOGqcY="},{"name":"virtualmachines/status","singularName":"","namespaced":true,"kind":"VirtualMachine","verbs":["get","patch","update"]},{"name":"virtualmachineinstancemigrations","singularName":"virtualmachineinstancemigration","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmim","vmims"],"categories":["all"],"storageVersionHash":"ByphcRAtdtg="},{"name":"virtualmachineinstancemigrations/status","singularName":"","namespaced":true,"kind":"VirtualMachineInstanceMigration","verbs":["get","patch","update"]},{"name":"virtualmachineinstancepresets","singularName":"virtualmachineinstancepreset","namespaced":true,"kind":"VirtualMachineInstancePreset","verbs":["delete","deletecollection","get","list","patch","create","update","watch"],"shortNames":["vmipreset","vmipresets"],"categories":["all"],"storageVersionHash":"oZZyVoiG8GU="}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/apis/kubevirt.io/v1/virtualmachineinstances
@@ -330,7 +246,7 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - d6d82e28-2fb3-4bf1-82ae-96f355674374
+      - b203e091-7f55-4285-847b-4ad4cebc3914
       Cache-Control:
       - no-cache, private
       Content-Type:
@@ -342,7 +258,7 @@ http_interactions:
       X-Kubernetes-Pf-Prioritylevel-Uid:
       - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Transfer-Encoding:
       - chunked
     body:
@@ -354,52 +270,10 @@ http_interactions:
         requires that all PVCs must be shared (using ReadWriteMany access mode)","reason":"DisksNotLiveMigratable","status":"False","type":"LiveMigratable"},{"lastProbeTime":"2025-02-26T18:45:45Z","lastTransitionTime":null,"status":"True","type":"AgentConnected"}],"currentCPUTopology":{"cores":1,"sockets":1,"threads":1},"guestOSInfo":{"id":"centos","kernelRelease":"5.14.0-570.el9.x86_64","kernelVersion":"#1
         SMP PREEMPT_DYNAMIC Mon Feb 17 19:45:23 UTC 2025","machine":"x86_64","name":"CentOS
         Stream","prettyName":"CentOS Stream 9","version":"9","versionId":"9"},"interfaces":[{"infoSource":"domain,
-        guest-agent","interfaceName":"eth0","ipAddress":"10.217.0.250","ipAddresses":["10.217.0.250"],"mac":"02:64:2d:00:00:02","name":"default","queueCount":1}],"launcherContainerImageVersion":"registry.redhat.io/container-native-virtualization/virt-launcher-rhel9@sha256:5ba79dd6bdf9e3778d3e301919b37e45cfc1eaf72fda77eba6588788829ba29b","machine":{"type":"pc-q35-rhel9.4.0"},"memory":{"guestAtBoot":"2Gi","guestCurrent":"2Gi","guestRequested":"2Gi"},"migrationMethod":"BlockMigration","migrationTransport":"Unix","nodeName":"crc","phase":"Running","phaseTransitionTimestamps":[{"phase":"Pending","phaseTransitionTimestamp":"2025-02-26T18:44:54Z"},{"phase":"Scheduling","phaseTransitionTimestamp":"2025-02-26T18:44:54Z"},{"phase":"Scheduled","phaseTransitionTimestamp":"2025-02-26T18:45:30Z"},{"phase":"Running","phaseTransitionTimestamp":"2025-02-26T18:45:33Z"}],"qosClass":"Burstable","runtimeUser":107,"selinuxContext":"system_u:object_r:container_file_t:s0:c281,c748","virtualMachineRevisionName":"revision-start-vm-fb22c624-ae4c-4e1e-8fd9-7e7a7aadde76-1","volumeStatus":[{"name":"cloudinitdisk","size":1048576,"target":"vdb"},{"name":"rootdisk","persistentVolumeClaimInfo":{"accessModes":["ReadWriteOnce"],"capacity":{"storage":"127Gi"},"claimName":"centos-stream9-lavender-manatee-97","filesystemOverhead":"0.055","requests":{"storage":"34087042032"},"volumeMode":"Filesystem"},"target":"vda"}]}}],"kind":"VirtualMachineInstanceList","metadata":{"continue":"","resourceVersion":"1115115"}}
-
-        '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
-- request:
-    method: get
-    uri: https://host.example.com:8443/apis/template.openshift.io
-    body:
-      encoding: US-ASCII
-      string: ''
-    headers:
-      Accept:
-      - "*/*"
-      User-Agent:
-      - rest-client/2.1.0 (linux-gnu x86_64) ruby/3.3.7p123
-      Authorization:
-      - Bearer theToken
-      Accept-Encoding:
-      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
-  response:
-    status:
-      code: 200
-      message: OK
-    headers:
-      Audit-Id:
-      - 46b00058-e1a0-45b2-8a04-ac7f5f0a9a2e
-      Cache-Control:
-      - no-cache, private
-      Content-Type:
-      - application/json
-      Strict-Transport-Security:
-      - max-age=31536000; includeSubDomains; preload
-      X-Kubernetes-Pf-Flowschema-Uid:
-      - 1deef9d8-0e80-4942-b8f4-7f15731ec1ac
-      X-Kubernetes-Pf-Prioritylevel-Uid:
-      - 7aec329e-b4b2-4fa2-af06-d4f660ca25ec
-      Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
-      Content-Length:
-      - '219'
-    body:
-      encoding: UTF-8
-      string: '{"kind":"APIGroup","apiVersion":"v1","name":"template.openshift.io","versions":[{"groupVersion":"template.openshift.io/v1","version":"v1"}],"preferredVersion":{"groupVersion":"template.openshift.io/v1","version":"v1"}}
+        guest-agent","interfaceName":"eth0","ipAddress":"10.217.0.250","ipAddresses":["10.217.0.250"],"mac":"02:64:2d:00:00:02","name":"default","queueCount":1}],"launcherContainerImageVersion":"registry.redhat.io/container-native-virtualization/virt-launcher-rhel9@sha256:5ba79dd6bdf9e3778d3e301919b37e45cfc1eaf72fda77eba6588788829ba29b","machine":{"type":"pc-q35-rhel9.4.0"},"memory":{"guestAtBoot":"2Gi","guestCurrent":"2Gi","guestRequested":"2Gi"},"migrationMethod":"BlockMigration","migrationTransport":"Unix","nodeName":"crc","phase":"Running","phaseTransitionTimestamps":[{"phase":"Pending","phaseTransitionTimestamp":"2025-02-26T18:44:54Z"},{"phase":"Scheduling","phaseTransitionTimestamp":"2025-02-26T18:44:54Z"},{"phase":"Scheduled","phaseTransitionTimestamp":"2025-02-26T18:45:30Z"},{"phase":"Running","phaseTransitionTimestamp":"2025-02-26T18:45:33Z"}],"qosClass":"Burstable","runtimeUser":107,"selinuxContext":"system_u:object_r:container_file_t:s0:c281,c748","virtualMachineRevisionName":"revision-start-vm-fb22c624-ae4c-4e1e-8fd9-7e7a7aadde76-1","volumeStatus":[{"name":"cloudinitdisk","size":1048576,"target":"vdb"},{"name":"rootdisk","persistentVolumeClaimInfo":{"accessModes":["ReadWriteOnce"],"capacity":{"storage":"127Gi"},"claimName":"centos-stream9-lavender-manatee-97","filesystemOverhead":"0.055","requests":{"storage":"34087042032"},"volumeMode":"Filesystem"},"target":"vda"}]}}],"kind":"VirtualMachineInstanceList","metadata":{"continue":"","resourceVersion":"1115930"}}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/apis/template.openshift.io/v1
@@ -421,8 +295,8 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - 15714e64-5816-4df4-8581-241341f86884
-      - 15714e64-5816-4df4-8581-241341f86884
+      - b7bac908-9f42-451e-85cb-7c9bf7a0e85c
+      - b7bac908-9f42-451e-85cb-7c9bf7a0e85c
       Cache-Control:
       - no-cache, private
       - no-store
@@ -431,7 +305,7 @@ http_interactions:
       Content-Type:
       - application/json
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Strict-Transport-Security:
       - max-age=31536000; includeSubDomains; preload
       X-Kubernetes-Pf-Flowschema-Uid:
@@ -443,7 +317,7 @@ http_interactions:
       string: '{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"template.openshift.io/v1","resources":[{"name":"brokertemplateinstances","singularName":"brokertemplateinstance","namespaced":false,"kind":"BrokerTemplateInstance","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"storageVersionHash":"Jxj8HlN0pXU="},{"name":"processedtemplates","singularName":"processedtemplate","namespaced":true,"kind":"Template","verbs":["create"]},{"name":"templateinstances","singularName":"templateinstance","namespaced":true,"kind":"TemplateInstance","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"storageVersionHash":"Q8UwfyPqly4="},{"name":"templateinstances/status","singularName":"","namespaced":true,"kind":"TemplateInstance","verbs":["get","patch","update"]},{"name":"templates","singularName":"template","namespaced":true,"kind":"Template","verbs":["create","delete","deletecollection","get","list","patch","update","watch"],"storageVersionHash":"utuWisMumJk="}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 - request:
     method: get
     uri: https://host.example.com:8443/apis/template.openshift.io/v1/templates
@@ -465,15 +339,15 @@ http_interactions:
       message: OK
     headers:
       Audit-Id:
-      - 9a8d1ce2-a36c-4a12-9912-ff9ac8cc7590
-      - 9a8d1ce2-a36c-4a12-9912-ff9ac8cc7590
+      - b11277ec-865d-4cfa-9d3f-6e3497f8fea8
+      - b11277ec-865d-4cfa-9d3f-6e3497f8fea8
       Cache-Control:
       - no-cache, private
       - no-store
       Content-Type:
       - application/json
       Date:
-      - Wed, 26 Feb 2025 19:04:23 GMT
+      - Wed, 26 Feb 2025 19:06:32 GMT
       Strict-Transport-Security:
       - max-age=31536000; includeSubDomains; preload
       X-Kubernetes-Pf-Flowschema-Uid:
@@ -484,7 +358,7 @@ http_interactions:
       - chunked
     body:
       encoding: UTF-8
-      string: '{"kind":"TemplateList","apiVersion":"template.openshift.io/v1","metadata":{"resourceVersion":"1115115"},"items":[{"metadata":{"name":"cache-service","namespace":"openshift","uid":"e42c607f-a6ac-4a34-9a75-2f50326ef39d","resourceVersion":"11135","creationTimestamp":"2025-02-09T10:45:00Z","labels":{"samples.operator.openshift.io/managed":"true","template":"cache-service"},"annotations":{"description":"Red
+      string: '{"kind":"TemplateList","apiVersion":"template.openshift.io/v1","metadata":{"resourceVersion":"1115930"},"items":[{"metadata":{"name":"cache-service","namespace":"openshift","uid":"e42c607f-a6ac-4a34-9a75-2f50326ef39d","resourceVersion":"11135","creationTimestamp":"2025-02-09T10:45:00Z","labels":{"samples.operator.openshift.io/managed":"true","template":"cache-service"},"annotations":{"description":"Red
         Hat Data Grid is an in-memory, distributed key/value store.","iconClass":"icon-datagrid","openshift.io/display-name":"Red
         Hat Cache Service","openshift.io/documentation-url":"https://access.redhat.com/documentation/en-us/red_hat_data_grid/7.3/html/red_hat_data_grid_for_openshift/","openshift.io/long-description":"Red
         Hat Data Grid Cache Service is an implementation of Data Grid for OpenShift
@@ -4452,5 +4326,5 @@ http_interactions:
         of the DataSource","value":"openshift-virtualization-os-images"}]}]}
 
         '
-  recorded_at: Wed, 26 Feb 2025 19:04:23 GMT
+  recorded_at: Wed, 26 Feb 2025 19:06:32 GMT
 recorded_with: VCR 6.3.1


Reviews:
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:21:36Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:22:14Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:22:44Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:23:41Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:25:34Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-18T21:30:24Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-26T19:52:59Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-26T20:39:41Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-26T22:00:22Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:05:31Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:06:15Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:06:55Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:09:28Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:10:57Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:12:05Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:16:04Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:22:22Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:22:39Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:24:29Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:25:09Z
user: login: Fryguy
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:32:30Z
user: login: agrare
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T16:48:49Z

Review comments:
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: I would expect the logger to come in from the opts otherwise we should probably default to a null logger (or just not set it)
created_at: 2025-02-18T21:21:36Z
author_association: MEMBER
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: Oh wait, nvm, I thought I was in the sdk gem, but this is manageiq-providers-kubevirt.
created_at: 2025-02-18T21:22:14Z
author_association: MEMBER
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
+    kubevirt_api_client.config.debugging  = Settings.log.level == "debug"
+    kubevirt_api_client.default_headers["Authorization"] = "Bearer #{api_key}"
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: Modifying the default headers seems weird to me? Is that just how the interface works?
created_at: 2025-02-18T21:22:44Z
author_association: MEMBER
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: Yeah I just copied the use of `$log` from the existing Connection class, but per the note we should add a kubevirt logger
created_at: 2025-02-18T21:23:41Z
author_association: MEMBER
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
+    kubevirt_api_client.config.debugging  = Settings.log.level == "debug"
+    kubevirt_api_client.default_headers["Authorization"] = "Bearer #{api_key}"
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: Agree it was weird to me also, it seems like an openapi thing since we do the same in powervs https://github.com/ManageIQ/manageiq-providers-ibm_cloud/blob/master/app/models/manageiq/providers/ibm_cloud/power_virtual_servers/manager_mixin.rb#L27

I think if the openapi spec declared an auth setting then the openapi generator would handle this for you, so far this was the only way to get the openapi generated gem to send authorization headers.
created_at: 2025-02-18T21:25:34Z
author_association: MEMBER
diff_hunk: @@ -1,12 +1,14 @@
 module ManageIQ::Providers::Kubevirt::InfraManager::Vm::Operations::Guest
 
   def raw_reboot_guest
-    kubevirt = ext_management_system.parent_manager.connect(:service => "kubernetes", :path => "/apis/subresources.kubevirt.io", :version => "v1")
-    kubevirt.rest_client["namespaces/#{location}/virtualmachineinstances/#{name}/softreboot"].put({}.to_json, { 'Content-Type' => 'application/json' }.merge(kubevirt.get_headers))
path: app/models/manageiq/providers/kubevirt/infra_manager/vm/operations/guest.rb
user: login: agrare
body: This was a good example of a method call that kubeclient couldn't handle, and `oc vm` can't do either and you have to use virtctl for.  (This was always gross but didn't want to block @Dhamo1107 from adding support for this while he was waiting for me to do this change).
created_at: 2025-02-18T21:30:24Z
author_association: MEMBER
diff_hunk: @@ -122,13 +123,20 @@ def self.verify_credentials(args)
   # @option opts [String] :token The Kubernetes authentication token.
   #
   def self.raw_connect(opts)
-    # Create the connection:
-    Connection.new(
-      :host      => opts[:server],
-      :port      => opts[:port],
-      :token     => ManageIQ::Password.try_decrypt(opts[:token]),
-      :namespace => "" # Collect resources across all namespaces
-    )
+    require "kubevirt"
+
+    api_key = ManageIQ::Password.try_decrypt(opts[:token])
+
+    kubevirt_api_client = Kubevirt::ApiClient.new
+    kubevirt_api_client.config.api_key    = api_key
+    kubevirt_api_client.config.scheme     = "https"
+    kubevirt_api_client.config.host       = "#{opts[:server]}:#{opts[:port] || 6443}"
+    kubevirt_api_client.config.verify_ssl = false # TODO check security_protocol
+    kubevirt_api_client.config.logger     = $log # TODO add a kubevirt logger
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: https://github.com/ManageIQ/manageiq-providers-kubevirt/pull/279
created_at: 2025-02-26T19:52:59Z
author_association: MEMBER
diff_hunk: @@ -109,7 +109,8 @@ def self.params_for_create
 
   def self.verify_credentials(args)
     kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token")&.symbolize_keys)
-    kubevirt&.valid? && kubevirt&.virt_supported?
+    kubevirt&.get_api_group_list
+    kubevirt&.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: TODO I need to confirm this behavior on a cluster that doesn't have kubevirt/osv installed
created_at: 2025-02-26T20:39:41Z
author_association: MEMBER
diff_hunk: @@ -109,7 +109,8 @@ def self.params_for_create
 
   def self.verify_credentials(args)
     kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token")&.symbolize_keys)
-    kubevirt&.valid? && kubevirt&.virt_supported?
+    kubevirt&.get_api_group_list
+    kubevirt&.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: ![image](https://github.com/user-attachments/assets/e353ae42-06da-404b-b191-4574fbc72102)

created_at: 2025-02-26T22:00:22Z
author_association: MEMBER
diff_hunk: @@ -109,7 +109,8 @@ def self.params_for_create
 
   def self.verify_credentials(args)
     kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token")&.symbolize_keys)
-    kubevirt&.valid? && kubevirt&.virt_supported?
+    kubevirt&.get_api_group_list
+    kubevirt&.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: Are we still waiting on this verification?
created_at: 2025-03-06T16:05:31Z
author_association: MEMBER
diff_hunk: @@ -150,7 +168,17 @@ def has_credentials?(_type = nil)
   # @param opts [Hash] Additional options to control how to perform the verification.
   #
   def verify_credentials(_type = nil, opts = {})
-    with_provider_connection(opts, &:valid?)
+    with_provider_connection(opts) do |kubevirt|
+      # First check that we're able to connect to the k8s API
+      kubevirt.get_api_group_list
+      # Then check that we can access the /apis/kubevirt.io API group
+      kubevirt.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: Since we're doing this in 2 spots, I wonder if we should move this into a method.
created_at: 2025-03-06T16:06:15Z
author_association: MEMBER
diff_hunk: @@ -150,7 +168,17 @@ def has_credentials?(_type = nil)
   # @param opts [Hash] Additional options to control how to perform the verification.
   #
   def verify_credentials(_type = nil, opts = {})
-    with_provider_connection(opts, &:valid?)
+    with_provider_connection(opts) do |kubevirt|
+      # First check that we're able to connect to the k8s API
+      kubevirt.get_api_group_list
+      # Then check that we can access the /apis/kubevirt.io API group
+      kubevirt.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: Fryguy
body: ~~Actually is this a duiplicate method in the same file?~~ Oh I just noticed class method vs instance method.  Still, I think we need a `verify_connection(connection)` method that just does these 2 things
created_at: 2025-03-06T16:06:55Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: Fryguy
body: Very minor, but:

```suggestion
    template.parameters.each_with_object({}) do |param, default_params|
      name = param[:name].downcase
      value = options[name.to_sym]
      if value && name == "memory"
        value = "#{value}Mi"
      end

      default_params[name] = value || param[:value]
    end
```
created_at: 2025-03-06T16:09:28Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: Fryguy
body: Can this be 

```suggestion
      result.transform_values! { |v| param_substitution!(v, params) }
```
created_at: 2025-03-06T16:10:57Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
+    when Array
+      result.map { |v| param_substitution!(v, params) }
+    when String
+      result = sub_specific_object(params, object)
+    end
+    result
+  end
+
+  #
+  # Performs substitution on specific object.
+  #
+  # @params params [Hash] Containing parameter names and values used for substitution.
+  # @params object [String] Object on which substitution takes place.
+  # @returns [String] The outcome of substitution.
+  #
+  def sub_specific_object(params, object)
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: Fryguy
body: Method name is weird to me - thinking `substitute_string` or `substitute_literal`.  Not important for merge.
created_at: 2025-03-06T16:12:05Z
author_association: MEMBER
diff_hunk: @@ -26,18 +25,43 @@ def log_clone_options(clone_options)
   end
 
   def start_clone(options)
-    # Retrieve the details of the source template:
-    template = nil
-    source.with_provider_connection(:namespace => source.location) do |connection|
-      template = connection.template(source.name)
-      template.clone(user_options(options))
+    source.with_provider_connection do |connection|
+      # Retrieve the details of the source template:
+      template    = source.provider_object
+      namespace ||= source.location
 
-      vm = connection.vm(options[:name])
+      params    = values(template, user_options(options))
+      pvc_specs = template.objects.select { |o| o[:kind] == "PersistentVolumeClaim" }&.map(&:to_h)
+      vm_spec   = template.objects.detect { |o| o[:kind] == "VirtualMachine" }&.to_h
+      raise N_("No Virtual Machine defined in template") if vm_spec.nil?
 
-      phase_context[:new_vm_ems_ref] = vm.uid
+      param_substitution!(vm_spec, params)
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: Fryguy
body: Is this a new feature? I don't see it in any of the deleted code, and it didn't do any of this previously.
created_at: 2025-03-06T16:16:04Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
+    when Array
+      result.map { |v| param_substitution!(v, params) }
+    when String
+      result = sub_specific_object(params, object)
+    end
+    result
+  end
+
+  #
+  # Performs substitution on specific object.
+  #
+  # @params params [Hash] Containing parameter names and values used for substitution.
+  # @params object [String] Object on which substitution takes place.
+  # @returns [String] The outcome of substitution.
+  #
+  def sub_specific_object(params, object)
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: agrare
body: This came from fog-kubevirt https://github.com/fog/fog-kubevirt/blob/master/lib/fog/kubevirt/compute/models/template.rb#L189-L206
created_at: 2025-03-06T16:22:22Z
author_association: MEMBER
diff_hunk: @@ -26,18 +25,43 @@ def log_clone_options(clone_options)
   end
 
   def start_clone(options)
-    # Retrieve the details of the source template:
-    template = nil
-    source.with_provider_connection(:namespace => source.location) do |connection|
-      template = connection.template(source.name)
-      template.clone(user_options(options))
+    source.with_provider_connection do |connection|
+      # Retrieve the details of the source template:
+      template    = source.provider_object
+      namespace ||= source.location
 
-      vm = connection.vm(options[:name])
+      params    = values(template, user_options(options))
+      pvc_specs = template.objects.select { |o| o[:kind] == "PersistentVolumeClaim" }&.map(&:to_h)
+      vm_spec   = template.objects.detect { |o| o[:kind] == "VirtualMachine" }&.to_h
+      raise N_("No Virtual Machine defined in template") if vm_spec.nil?
 
-      phase_context[:new_vm_ems_ref] = vm.uid
+      param_substitution!(vm_spec, params)
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: agrare
body: This was done by fog-kubevirt https://github.com/fog/fog-kubevirt/blob/master/lib/fog/kubevirt/compute/models/template.rb#L167-L180
created_at: 2025-03-06T16:22:38Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: agrare
body: This was another method from fog-kubevirt, https://github.com/fog/fog-kubevirt/blob/master/lib/fog/kubevirt/compute/models/template.rb#L59-L71

In general I tried to not change these too much other than really obvious stuff so we weren't changing too many things at once
created_at: 2025-03-06T16:24:29Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: agrare
body: Sure
created_at: 2025-03-06T16:25:09Z
author_association: MEMBER
diff_hunk: @@ -54,4 +78,60 @@ def user_options(options)
     merged_options[:cloud_user_password] = ManageIQ::Password.try_decrypt(get_option(:root_password))
     merged_options.compact
   end
+
+  def values(template, options)
+    default_params = {}
+    template.parameters.each do |param|
+      name = param[:name].downcase
+      value = options[name.to_sym]
+      if value && name == "memory"
+        value = "#{value}Mi"
+      end
+
+      default_params[name] = value || param[:value]
+    end
+    default_params
+  end
+
+  def param_substitution!(object, params)
+    result = object
+    case result
+    when Hash
+      result.each do |k, v|
+        result[k] = param_substitution!(v, params)
+      end
path: app/models/manageiq/providers/kubevirt/infra_manager/provision/cloning.rb
user: login: Fryguy
body: Oh I didn't realize this came from elsewhere - it can be changed separately.
created_at: 2025-03-06T16:32:30Z
author_association: MEMBER
diff_hunk: @@ -109,7 +109,8 @@ def self.params_for_create
 
   def self.verify_credentials(args)
     kubevirt = raw_connect(args.dig("endpoints", "default")&.slice("server", "port", "token")&.symbolize_keys)
-    kubevirt&.valid? && kubevirt&.virt_supported?
+    kubevirt&.get_api_group_list
+    kubevirt&.get_api_group_kubevirt_io
path: app/models/manageiq/providers/kubevirt/infra_manager.rb
user: login: agrare
body: No, above screenshot shows it working
created_at: 2025-03-06T16:48:48Z
author_association: MEMBER

PR comments:
user: login: Fryguy
created_at: 2025-02-18T21:20:12Z
body: Nice - I assume we'll want to publish kubevirt-sdk-ruby under the ManageIQ org first?
author_association: MEMBER
user: login: agrare
created_at: 2025-02-18T21:21:23Z
body: Yes, still a good amount of work to do to move over to using the new gem so no rush on transfer
author_association: MEMBER
user: login: Fryguy
created_at: 2025-02-18T21:23:45Z
body: This is really cool - looking forward to see how this turns out.

author_association: MEMBER
user: login: agrare
created_at: 2025-02-27T20:27:06Z
body: @Fryguy okay I think we're at the point where we can start moving kubevirt-sdk-ruby to the ManageIQ org and doing a gem release
author_association: MEMBER
user: login: Fryguy
created_at: 2025-02-27T22:26:51Z
body: @agrare https://github.com/ManageIQ/kubevirt-sdk-ruby is ready to go.  There might be some minor cleanup, then you can cut the gem.  Please include me as a backup owner when you do.
author_association: MEMBER
user: login: miq-bot
created_at: 2025-03-05T19:19:38Z
body: <rubocop />Checked commits https://github.com/agrare/manageiq-providers-kubevirt/compare/1ff01de506281f752730488b258fd0d52d39d68b~...fe3895780ae51ed5568011d16696c9fc0bd10056 with ruby 3.1.5, rubocop 1.56.3, haml-lint 0.51.0, and yamllint 
18 files checked, 2 offenses detected

**app/models/manageiq/providers/kubevirt/infra_manager.rb**
- [ ] :exclamation: - [Line 145](https://github.com/agrare/manageiq-providers-kubevirt/blob/fe3895780ae51ed5568011d16696c9fc0bd10056/app/models/manageiq/providers/kubevirt/infra_manager.rb#L145), Col 45 - [Style/GlobalVars](https://docs.rubocop.org/rubocop/1.56/cops_style.html#styleglobalvars) - Do not introduce global variables.
- [ ] :exclamation: - [Line 179](https://github.com/agrare/manageiq-providers-kubevirt/blob/fe3895780ae51ed5568011d16696c9fc0bd10056/app/models/manageiq/providers/kubevirt/infra_manager.rb#L179), Col 7 - [Layout/EmptyLineAfterGuardClause](https://docs.rubocop.org/rubocop/1.56/cops_layout.html#layoutemptylineafterguardclause) - Add empty line after guard clause.

author_association: MEMBER
user: login: Fryguy
created_at: 2025-03-06T16:33:07Z
body: Ok, don't worry about the copied code - that can all be done separately.
author_association: MEMBER