Class: Katello::Host::SubscriptionFacet

Inherits:
Model
  • Object
show all
Includes:
DirtyAssociations, Facets::Base
Defined in:
app/models/katello/host/subscription_facet.rb

Constant Summary collapse

DEFAULT_TYPE =
'system'.freeze
DMI_UUID_ALLOWED_DUPS =
['', 'Not Settable', 'Not Present'].freeze
DMI_UUID_OVERRIDE_PARAM =
'dmi_uuid_override'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Model

#destroy!

Instance Attribute Details

#factsObject

Returns the value of attribute facts.



34
35
36
# File 'app/models/katello/host/subscription_facet.rb', line 34

def facts
  @facts
end

Class Method Details

.ignore_os?(host_os, rhsm_facts) ⇒ Boolean

Returns:

  • (Boolean)


222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'app/models/katello/host/subscription_facet.rb', line 222

def self.ignore_os?(host_os, rhsm_facts)
  if host_os.nil?
    return false
  end

  name = rhsm_facts['distribution.name']
  version = rhsm_facts['distribution.version']
  major, minor = version&.split('.')
  return host_os.name == 'CentOS' &&
    !host_os.major.nil? &&
    name == 'CentOS' &&
    minor.blank? &&
    host_os.major == major
end

.new_host_from_facts(facts, org, location) ⇒ Object



207
208
209
210
# File 'app/models/katello/host/subscription_facet.rb', line 207

def self.new_host_from_facts(facts, org, location)
  name = propose_name_from_facts(facts)
  ::Host::Managed.new(:name => name, :organization => org, :location => location, :managed => false)
end

.override_dmi_uuid?(host_uuid) ⇒ Boolean

Returns:

  • (Boolean)


203
204
205
# File 'app/models/katello/host/subscription_facet.rb', line 203

def self.override_dmi_uuid?(host_uuid)
  Setting[:host_dmi_uuid_duplicates].include?(host_uuid)
end

.propose_custom_fact(facts) ⇒ Object



247
248
249
250
251
252
253
254
255
256
# File 'app/models/katello/host/subscription_facet.rb', line 247

def self.propose_custom_fact(facts)
  setting_fact = Setting[:register_hostname_fact]
  only_use_custom_fact = Setting[:register_hostname_fact_strict_match]

  if !setting_fact.blank? && !facts[setting_fact].blank?
    if only_use_custom_fact || ::Host.where(:name => setting_fact.downcase).any?
      facts[setting_fact]
    end
  end
end

.propose_existing_hostname(facts) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'app/models/katello/host/subscription_facet.rb', line 258

def self.propose_existing_hostname(facts)
  if propose_custom_fact(facts)
    name = propose_custom_fact(facts)
  elsif ::Host.where(:name => facts['network.hostname'].downcase).any?
    name = facts['network.hostname']
  elsif !facts['network.fqdn'].blank? && ::Host.where(:name => facts['network.fqdn'].downcase).any?
    name = facts['network.fqdn']
  elsif !facts['network.hostname-override'].blank? && ::Host.where(:name => facts['network.hostname-override'].downcase).any?
    name = facts['network.hostname-override']
  else
    name = facts['network.hostname'] #fallback to default, even if it doesn't exist
  end

  name.downcase
end

.propose_name_from_facts(facts) ⇒ Object



237
238
239
240
241
242
243
244
245
# File 'app/models/katello/host/subscription_facet.rb', line 237

def self.propose_name_from_facts(facts)
  setting_fact = Setting[:register_hostname_fact]
  if !setting_fact.blank? && facts[setting_fact] && facts[setting_fact] != 'localhost'
    facts[setting_fact]
  else
    Rails.logger.warn(_("register_hostname_fact set for %s, but no fact found, or was localhost.") % setting_fact) unless setting_fact.blank?
    [facts['network.fqdn'], facts['network.hostname-override'], facts['network.hostname']].find { |name| !name.blank? && name != 'localhost' }
  end
end

.sanitize_name(name) ⇒ Object



282
283
284
# File 'app/models/katello/host/subscription_facet.rb', line 282

def self.sanitize_name(name)
  name.gsub('_', '-').chomp('.').downcase
end

.update_facts(host, rhsm_facts) ⇒ Object



212
213
214
215
216
217
218
219
220
# File 'app/models/katello/host/subscription_facet.rb', line 212

def self.update_facts(host, rhsm_facts)
  return if host.build? || rhsm_facts.nil?
  rhsm_facts[:_type] = RhsmFactName::FACT_TYPE
  rhsm_facts[:_timestamp] = Time.now.to_s
  if ignore_os?(host.operatingsystem, rhsm_facts)
    rhsm_facts[:ignore_os] = true
  end
  ::HostFactImporter.new(host).import_facts(rhsm_facts)
end

Instance Method Details

#backend_update_needed?Boolean

Returns:

  • (Boolean)


294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'app/models/katello/host/subscription_facet.rb', line 294

def backend_update_needed?
  %w(release_version service_level autoheal purpose_role purpose_usage purpose_addon_ids).each do |method|
    if self.send("#{method}_changed?")
      Rails.logger.debug("backend_update_needed: subscription facet #{method} changed")
      return true
    end
  end
  facet = self.host&.content_facet
  if facet&.cves_changed? && !facet.new_record?
    Rails.logger.debug("backend_update_needed: content facet CVEs changed")
    return true
  end
  false
end

#candlepin_consumerObject



290
291
292
# File 'app/models/katello/host/subscription_facet.rb', line 290

def candlepin_consumer
  @candlepin_consumer ||= Katello::Candlepin::Consumer.new(self.uuid, self.host.organization.label)
end

#candlepin_environmentsObject



156
157
158
159
160
161
162
163
164
# File 'app/models/katello/host/subscription_facet.rb', line 156

def candlepin_environments
  if self.host.content_facet
    self.host.content_facet.content_view_environments.map do |cve|
      { :id => cve.content_view.cp_environment_id(cve.lifecycle_environment) }
    end
  else
    self.host.organization.default_content_view.cp_environment_id(self.host.organization.library)
  end
end

#consumer_attributesObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'app/models/katello/host/subscription_facet.rb', line 140

def consumer_attributes
  attrs = {
    :autoheal => autoheal,
    :usage => purpose_usage,
    :role => purpose_role,
    :addOns => purpose_addons.pluck(:name),
    :serviceLevel => service_level,
    :releaseVer => release_version,
    :environments => self.candlepin_environments,
    :installedProducts => self.installed_products.map(&:consumer_attributes),
    :guestIds => virtual_guest_uuids
  }
  attrs[:facts] = facts if facts
  HashWithIndifferentAccess.new(attrs)
end

#content_view_environmentsObject



166
167
168
# File 'app/models/katello/host/subscription_facet.rb', line 166

def content_view_environments
  self.host.content_facet.try(:content_view_environments)
end

#dmi_uuid_overrideObject



174
175
176
# File 'app/models/katello/host/subscription_facet.rb', line 174

def dmi_uuid_override
  HostParameter.find_by(name: DMI_UUID_OVERRIDE_PARAM, host: host)
end

#host_typeObject



41
42
43
44
# File 'app/models/katello/host/subscription_facet.rb', line 41

def host_type
  host_facts = self.host.facts
  host_facts["virt::host_type"] || host_facts["hypervisor::type"]
end

#import_database_attributes(consumer_params = candlepin_consumer.consumer_attributes) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/models/katello/host/subscription_facet.rb', line 51

def import_database_attributes(consumer_params = candlepin_consumer.consumer_attributes)
  update_subscription_status(consumer_params[:entitlementStatus]) unless consumer_params[:entitlementStatus].blank?
  update_hypervisor(consumer_params)
  update_guests(consumer_params)

  if consumer_params['facts']
    self.dmi_uuid = consumer_params['facts']['dmi.system.uuid']
  end

  self.autoheal = consumer_params['autoheal'] unless consumer_params['autoheal'].nil?
  self.service_level = consumer_params['serviceLevel'] unless consumer_params['serviceLevel'].nil?
  self.registered_at = consumer_params['created'] unless consumer_params['created'].blank?
  self.last_checkin = consumer_params['lastCheckin'] unless consumer_params['lastCheckin'].blank?
  self.update_installed_products(consumer_params['installedProducts']) if consumer_params.key?('installedProducts')
  self.purpose_role = consumer_params['role'] unless consumer_params['role'].nil?
  self.purpose_usage = consumer_params['usage'] unless consumer_params['usage'].nil?
  unless consumer_params['addOns'].nil?
    self.purpose_addon_ids = consumer_params['addOns'].map { |addon_name| ::Katello::PurposeAddon.find_or_create_by(name: addon_name).id }
  end

  unless consumer_params['releaseVer'].blank?
    release = consumer_params['releaseVer']
    release = release['releaseVer'] if release.is_a?(Hash)
    self.release_version = release
  end
end

#organizationObject



170
171
172
# File 'app/models/katello/host/subscription_facet.rb', line 170

def organization
  self.host.organization
end

#productsObject



274
275
276
# File 'app/models/katello/host/subscription_facet.rb', line 274

def products
  Katello::Product.joins(:subscriptions => {:pools => :subscription_facets}).where("#{Katello::Host::SubscriptionFacet.table_name}.id" => self.id).enabled.uniq
end

#remove_subscriptions(pools_with_quantities) ⇒ Object



278
279
280
# File 'app/models/katello/host/subscription_facet.rb', line 278

def remove_subscriptions(pools_with_quantities)
  ForemanTasks.sync_task(Actions::Katello::Host::RemoveSubscriptions, self.host, pools_with_quantities)
end

#unsubscribed_hypervisor?Boolean

Returns:

  • (Boolean)


286
287
288
# File 'app/models/katello/host/subscription_facet.rb', line 286

def unsubscribed_hypervisor?
  self.hypervisor && !self.candlepin_consumer.entitlements?
end

#update_compliance_reasons(reasons) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'app/models/katello/host/subscription_facet.rb', line 84

def update_compliance_reasons(reasons)
  reasons = Katello::Candlepin::Consumer.friendly_compliance_reasons(reasons)

  existing = self.compliance_reasons.pluck(:reason)
  to_delete = existing - reasons
  to_create = reasons - existing
  self.compliance_reasons.where(:reason => to_delete).destroy_all if to_delete.any?
  to_create.each { |reason| self.compliance_reasons.create(:reason => reason) }
end

#update_dmi_uuid_override(host_uuid = nil) ⇒ Object



178
179
180
181
182
183
# File 'app/models/katello/host/subscription_facet.rb', line 178

def update_dmi_uuid_override(host_uuid = nil)
  host_uuid ||= SecureRandom.uuid
  param = HostParameter.find_or_create_by(name: DMI_UUID_OVERRIDE_PARAM, host: host)
  param.update!(value: host_uuid)
  param
end

#update_from_consumer_attributes(consumer_params) ⇒ Object



46
47
48
49
# File 'app/models/katello/host/subscription_facet.rb', line 46

def update_from_consumer_attributes(consumer_params)
  import_database_attributes(consumer_params)
  self.facts = consumer_params['facts'] unless consumer_params['facts'].blank?
end

#update_guests(consumer_params) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/models/katello/host/subscription_facet.rb', line 113

def update_guests(consumer_params)
  if self.hypervisor
    if !consumer_params.try(:[], 'guestIds').empty?
      guest_ids = consumer_params['guestIds'].map do |id|
        case id
        when Hash
          id['guestId'].downcase
        when String
          id.downcase
        end
      end

      guest_ids = FactValue.where("lower(value) IN (?)", guest_ids).
                            where(:fact_name_id => FactName.where(:name => 'virt::uuid')).
                            pluck(:host_id)
    else
      guest_ids = self.candlepin_consumer.virtual_guests.pluck(:id)
    end

    subscription_facets = SubscriptionFacet.where(:host_id => guest_ids).
                                            where("hypervisor_host_id != ? OR hypervisor_host_id is NULL", self.host.id)
    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

#update_hypervisor(consumer_params = candlepin_consumer.consumer_attributes) ⇒ Object



102
103
104
105
106
107
108
109
110
111
# File 'app/models/katello/host/subscription_facet.rb', line 102

def update_hypervisor(consumer_params = candlepin_consumer.consumer_attributes)
  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

#update_installed_products(consumer_installed_product_list) ⇒ Object



78
79
80
81
82
# File 'app/models/katello/host/subscription_facet.rb', line 78

def update_installed_products(consumer_installed_product_list)
  self.installed_products = consumer_installed_product_list.map do |consumer_installed_product|
    InstalledProduct.find_or_create_from_consumer(consumer_installed_product)
  end
end

#update_purpose_status(sla_status: nil, role_status: nil, usage_status: nil, addons_status: nil, purpose_status: nil) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/katello/host/subscription_facet.rb', line 191

def update_purpose_status(sla_status: nil, role_status: nil, usage_status: nil, addons_status: nil, purpose_status: nil)
  # if this method is ever called such that we aren't sending the status params, we should pass along the candlepin_consumer
  # in order to reduce HTTP requests into candlepin for each Status
  update_status(::Katello::PurposeSlaStatus, status_override: sla_status)
  update_status(::Katello::PurposeRoleStatus, status_override: role_status)
  update_status(::Katello::PurposeUsageStatus, status_override: usage_status)
  update_status(::Katello::PurposeAddonsStatus, status_override: addons_status)
  update_status(::Katello::PurposeStatus, status_override: purpose_status)

  host.refresh_global_status!
end

#update_subscription_status(status_override = nil) ⇒ Object



185
186
187
188
189
# File 'app/models/katello/host/subscription_facet.rb', line 185

def update_subscription_status(status_override = nil)
  update_status(::Katello::SubscriptionStatus, status_override: status_override)

  host.refresh_global_status!
end

#virtual_guest_uuidsObject



98
99
100
# File 'app/models/katello/host/subscription_facet.rb', line 98

def virtual_guest_uuids
  virtual_guests.pluck("#{Katello::Host::SubscriptionFacet.table_name}.uuid")
end

#virtual_guestsObject



94
95
96
# File 'app/models/katello/host/subscription_facet.rb', line 94

def virtual_guests
  ::Host.joins(:subscription_facet).where("#{self.class.table_name}.hypervisor_host_id" => self.host_id)
end