Skip to content

Commit

Permalink
Fixes #17148: Allow searching for hypervisors
Browse files Browse the repository at this point in the history
  • Loading branch information
ehelms committed Jan 23, 2017
1 parent 1e8efa1 commit e99f9d6
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ def server_status
render :json => status
end

#api :PUT, "/consumers/:id", N_("Update consumer information")
def facts
sync_task(::Actions::Katello::Host::Update, @host, rhsm_params)
update_host_registered_through(@host, request.headers)
Expand Down
16 changes: 16 additions & 0 deletions app/models/katello/concerns/subscription_facet_host_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module SubscriptionFacetHostExtensions

has_many :activation_keys, :through => :subscription_facet
has_one :subscription_status_object, :class_name => 'Katello::SubscriptionStatus', :foreign_key => 'host_id'
has_one :hypervisor_host, :through => :subscription_facet

scoped_search :on => :status, :relation => :subscription_status_object, :rename => :subscription_status,
:complete_value => SUBSCRIPTION_STATUS_MAP

Expand All @@ -29,6 +31,8 @@ module SubscriptionFacetHostExtensions
scoped_search :relation => :activation_keys, :on => :name, :rename => :activation_key, :complete_value => true, :ext_method => :find_by_activation_key
scoped_search :relation => :activation_keys, :on => :id, :rename => :activation_key_id, :complete_value => true, :ext_method => :find_by_activation_key_id,
:only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
scoped_search :on => :hypervisor, :relation => :subscription_facet, :complete_value => true
scoped_search :on => :name, :relation => :hypervisor_host, :complete_value => true, :rename => :hypervisor_host, :ext_method => :find_by_hypervisor_host
end

def update_action
Expand Down Expand Up @@ -57,6 +61,18 @@ def find_by_activation_key_id(_key, operator, value)
{ :conditions => "#{::Host::Managed.table_name}.id IN (#{hosts.pluck(:id).join(',')})" }
end
end

def find_by_hypervisor_host(_key, operator, value)
conditions = sanitize_sql_for_conditions(["#{::Host.table_name}.name #{operator} ?", value_to_sql(operator, value)])
hosts = ::Host.where(conditions)
hosts = ::Host.joins(:subscription_facet).where("#{Katello::Host::SubscriptionFacet.table_name}.hypervisor_host_id" => hosts)

if hosts.empty?
{:conditions => "1=0"}
else
{:conditions => "#{::Host::Managed.table_name}.id IN (#{hosts.pluck(:id).join(',')})"}
end
end
end
end
end
Expand Down
25 changes: 25 additions & 0 deletions app/models/katello/host/subscription_facet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class SubscriptionFacet < Katello::Model
include Facets::Base

belongs_to :user, :inverse_of => :subscription_facets, :class_name => "::User"
belongs_to :hypervisor_host, :class_name => "::Host::Managed", :foreign_key => "hypervisor_host_id"

has_many :activation_keys, :through => :subscription_facet_activation_keys, :class_name => "Katello::ActivationKey"
has_many :subscription_facet_activation_keys, :class_name => "Katello::SubscriptionFacetActivationKey", :dependent => :destroy, :inverse_of => :subscription_facet
Expand All @@ -23,6 +24,9 @@ def update_from_consumer_attributes(consumer_params)
end

def import_database_attributes(consumer_params)
update_hypervisor(consumer_params)
update_guests

self.autoheal = consumer_params['autoheal'] unless consumer_params['autoheal'].blank?
self.service_level = consumer_params['serviceLevel'] unless consumer_params['serviceLevel'].blank?
self.registered_at = consumer_params['created'] unless consumer_params['created'].blank?
Expand All @@ -35,6 +39,27 @@ def import_database_attributes(consumer_params)
end
end

def update_hypervisor(consumer_params)
if consumer_params.try(:[], 'type').try(:[], 'label') == 'hypervisor'
self.hypervisor = true
elsif !consumer_params.try(:[], 'guestIds').empty?
self.hypervisor = true
elsif !candlepin_consumer.virtual_guests.empty?
# Check by calling out to Candlepin last for efficiency
self.hypervisor = true
end
end

def update_guests
if self.hypervisor
guests = self.candlepin_consumer.virtual_guests
subscription_facets = SubscriptionFacet.where(:host => guests)
subscription_facets.update_all(:hypervisor_host_id => self.host.id)
elsif (virtual_host = self.candlepin_consumer.virtual_host)
self.hypervisor_host = virtual_host
end
end

def consumer_attributes
attrs = {
:autoheal => autoheal,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddHypervisorToSubscriptionFacets < ActiveRecord::Migration
def change
add_column :katello_subscription_facets, :hypervisor, :boolean, :default => false
add_column :katello_subscription_facets, :hypervisor_host_id, :integer
end
end
17 changes: 17 additions & 0 deletions db/seeds.d/108-subcription-bookmarks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# !!! PLEASE KEEP THIS SCRIPT IDEMPOTENT !!!
#

Bookmark.without_auditing do
bookmarks = [
{:name => "list hypervisors", :query => 'hypervisor = true', :controller => "hosts"}
]

bookmarks.each do |input|
next if audit_modified? Bookmark, input[:name], :controller => input[:controller]
b = Bookmark.find_or_create_by({ :public => true }.merge(input))
fail "Unable to create bookmark: #{format_errors b}" if b.nil? || b.errors.any?
end
end
2 changes: 2 additions & 0 deletions lib/katello/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ def find_assets(args = {})
load "#{Katello::Engine.root}/lib/katello/tasks/import_applicability.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/clean_published_repo_directories.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/virt_who_report.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/update_subscription_facet_backend_data.rake"

load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/2.4/import_package_groups.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/2.4/import_rpms.rake"
Expand All @@ -278,6 +279,7 @@ def find_assets(args = {})
load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/3.0/update_puppet_repository_distributors.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/3.0/update_subscription_facet_backend_data.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/3.3/import_subscriptions.rake"
load "#{Katello::Engine.root}/lib/katello/tasks/upgrades/3.3/hypervisors.rake"
end
end

Expand Down
61 changes: 61 additions & 0 deletions lib/katello/tasks/update_subscription_facet_backend_data.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
namespace :katello do
task :update_subscription_facet_backend_data => ["environment"] do
def error(message)
@errors << message
@errors << "\n"
end

def report_errors
if @errors.any?
filename = "subscription_facet_upgrade-#{Time.now.to_i}.log"
path = "/var/log/foreman/#{filename}"
path = "/tmp/#{filename}" unless File.writable?(path)

file = File.open(path, 'w')
@errors.each { |error| file.write(error) }
file.close
$stderr.print "***********************************\n"
$stderr.print "*************WARNING***************\n"
$stderr.print "Errors detected during upgrade step.\n"
$stderr.print "Details saved to: #{file.path}\n"
$stderr.print "This step can be rerun with:\n"
$stderr.print " foreman-rake katello:update_subscription_facet_backend_data\n"
$stderr.print "You are likely encountering a bug.\n"
$stderr.print "***********************************\n"
end
end

@errors ||= []
User.current = User.anonymous_api_admin
puts _("Updating backend data for subscription facets")

#there may be some invalid hosts, if there are create a primary interface
::Host.includes(:interfaces).find_each do |host|
if host.primary_interface.nil?
host.interfaces.create!(:primary => true)
end
end

Katello::Host::SubscriptionFacet.find_each do |subscription_facet|
begin
candlepin_attrs = subscription_facet.candlepin_consumer.consumer_attributes
subscription_facet.import_database_attributes(candlepin_attrs)
subscription_facet.host = ::Host::Managed.find(subscription_facet.host_id)
subscription_facet.save!

host = subscription_facet.host
host.name = ::Katello::Host::SubscriptionFacet.sanitize_name(host.name)
host.save! if host.name_changed?

Katello::Host::SubscriptionFacet.update_facts(subscription_facet.host, candlepin_attrs[:facts])
rescue StandardError => exception
error("Error: #{subscription_facet.host.name} - #{subscription_facet.host.id}")
error(candlepin_attrs)
error(exception.message)
error(exception.backtrace.join("\n"))
error("\n")
end
end
report_errors
end
end
7 changes: 7 additions & 0 deletions lib/katello/tasks/upgrades/3.3/hypervisors.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace :katello do
namespace :upgrades do
namespace '3.3' do
task :hypervisors => ["katello:update_subscription_facet_backend_data"]
end
end
end
7 changes: 7 additions & 0 deletions test/lib/tasks/seeds_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,11 @@ class MailNotificationsTest < SeedsTest
assert MailNotification[:sync_errata]
end
end

class SubscriptionBookmarkstest < SeedsTest
test "Ensure hypervisor bookmark is created" do
seed
refute Bookmark.where(:name => "list hypervisors").empty?
end
end
end
60 changes: 60 additions & 0 deletions test/models/host/subscription_facet_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,65 @@ def test_propose_existing_hostname_fqdn_exists
facts = {'network.hostname' => 'foo', 'network.hostname-override' => 'baz.com'}
assert_equal 'foo', Host::SubscriptionFacet.propose_existing_hostname(facts)
end

def test_search_hypervisor
subscription_facet.hypervisor = "true"
subscription_facet.save!

assert_includes ::Host.search_for("hypervisor = true"), host
end

def test_search_hypervisor_host
subscription_facet.hypervisor = "true"
subscription_facet.save!
guest_host = FactoryGirl.create(:host, :with_content, :with_subscription, :content_view => view,
:lifecycle_environment => library, :organization => org)
subscription_facet.candlepin_consumer.expects(:virtual_guests).returns([guest_host])
subscription_facet.update_guests

assert_includes ::Host.search_for("hypervisor_host = #{host.name}"), guest_host
end

def test_update_hypervisor_using_candlepin_type
consumer_params = {'type' => {'label' => 'hypervisor'}}
subscription_facet.update_hypervisor(consumer_params)

assert subscription_facet.hypervisor
end

def test_update_hypervisor_using_guest_ids
consumer_params = {'guestIds' => ['1']}
subscription_facet.update_hypervisor(consumer_params)

assert subscription_facet.hypervisor
end

def test_update_hypervisor_via_candlepin_api
consumer_params = {}
subscription_facet.candlepin_consumer.expects(:virtual_guests).returns(['1'])
subscription_facet.update_hypervisor(consumer_params)

assert subscription_facet.hypervisor
end

def test_update_guests_for_hypervisor
guest_host = FactoryGirl.create(:host, :with_content, :with_subscription, :content_view => view,
:lifecycle_environment => library, :organization => org)
subscription_facet.hypervisor = true
subscription_facet.candlepin_consumer.expects(:virtual_guests).returns([guest_host])
subscription_facet.update_guests

assert_equal host, guest_host.subscription_facet.reload.hypervisor_host
end

def test_update_guests_for_guest
virt_host = FactoryGirl.create(:host, :with_content, :with_subscription, :content_view => view,
:lifecycle_environment => library, :organization => org)
subscription_facet.hypervisor = false
subscription_facet.candlepin_consumer.expects(:virtual_host).returns(virt_host)
subscription_facet.update_guests

assert_equal virt_host, subscription_facet.hypervisor_host
end
end
end

0 comments on commit e99f9d6

Please sign in to comment.