Class: Katello::Host::ContentFacet

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

Defined Under Namespace

Classes: Jail

Constant Summary collapse

HOST_TOOLS_PACKAGE_NAME =
'katello-host-tools'.freeze
HOST_TOOLS_TRACER_PACKAGE_NAME =
'katello-host-tools-tracer'.freeze
SUBSCRIPTION_MANAGER_PACKAGE_NAME =
'subscription-manager'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Model

#destroy!

Constructor Details

#initialize(*args) ⇒ ContentFacet

Returns a new instance of ContentFacet.



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/models/katello/host/content_facet.rb', line 45

def initialize(*args)
  init_args = args.first || {}
  env_id = init_args.delete(:lifecycle_environment_id)
  cv_id = init_args.delete(:content_view_id)
  super(*args)
  if env_id && cv_id
    assign_single_environment(
      lifecycle_environment_id: env_id,
      content_view_id: cv_id
    )
  end
  self.cves_changed = false
end

Instance Attribute Details

#cves_changedObject

Returns the value of attribute cves_changed.



43
44
45
# File 'app/models/katello/host/content_facet.rb', line 43

def cves_changed
  @cves_changed
end

Class Method Details

.in_content_view_version_environments(version_environments) ⇒ Object



221
222
223
224
225
226
227
228
229
230
# File 'app/models/katello/host/content_facet.rb', line 221

def self.in_content_view_version_environments(version_environments)
  # takes a structure of [{:content_view_version => ContentViewVersion, :environments => [KTEnvironment]}]
  relation = self.joins(:content_view_environment_content_facets => :content_view_environment)
  queries = version_environments.map do |version_environment|
    version = version_environment[:content_view_version]
    env_ids = version_environment[:environments].map(&:id)
    "(#{::Katello::ContentViewEnvironment.table_name}.content_view_version_id = #{version.id} AND #{::Katello::ContentViewEnvironment.table_name}.environment_id IN (#{env_ids.join(',')}))"
  end
  relation.where(queries.join(" OR "))
end

.in_content_views_and_environments(content_views: nil, lifecycle_environments: nil) ⇒ Object



232
233
234
235
236
237
# File 'app/models/katello/host/content_facet.rb', line 232

def self.in_content_views_and_environments(content_views: nil, lifecycle_environments: nil)
  relation = self.joins(:content_view_environment_content_facets => :content_view_environment)
  relation = relation.where("#{::Katello::ContentViewEnvironment.table_name}.content_view_id" => content_views) if content_views
  relation = relation.where("#{::Katello::ContentViewEnvironment.table_name}.environment_id" => lifecycle_environments) if lifecycle_environments
  relation
end

.inherited_attributes(hostgroup, facet_attributes) ⇒ Object



346
347
348
349
350
351
352
# File 'app/models/katello/host/content_facet.rb', line 346

def self.inherited_attributes(hostgroup, facet_attributes)
  facet_attributes[:kickstart_repository_id] ||= hostgroup.inherited_kickstart_repository_id
  facet_attributes[:content_view_id] ||= hostgroup.inherited_content_view_id
  facet_attributes[:lifecycle_environment_id] ||= hostgroup.inherited_lifecycle_environment_id
  facet_attributes[:content_source_id] ||= hostgroup.inherited_content_source_id
  facet_attributes
end

.joins_installable_debsObject



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

def self.joins_installable_debs
  joins_installable_relation(Katello::Deb, Katello::ContentFacetApplicableDeb)
end

.joins_installable_errataObject



270
271
272
# File 'app/models/katello/host/content_facet.rb', line 270

def self.joins_installable_errata
  joins_installable_relation(Katello::Erratum, Katello::ContentFacetErratum)
end

.joins_installable_relation(content_model, facet_join_model) ⇒ Object

TODO: uncomment when we need to display multiple CVE names in the UI def content_view_environment_names

content_view_environments.map(&:candlepin_name).join(', ')

end



333
334
335
336
337
338
339
340
341
342
343
344
# File 'app/models/katello/host/content_facet.rb', line 333

def self.joins_installable_relation(content_model, facet_join_model)
  facet_repository = Katello::ContentFacetRepository.table_name
  content_table = content_model.table_name
  facet_join_table = facet_join_model.table_name
  repo_join_table = content_model.repository_association_class.table_name

  self.joins("INNER JOIN #{facet_repository} on #{facet_repository}.content_facet_id = #{table_name}.id",
             "INNER JOIN #{repo_join_table} on #{repo_join_table}.repository_id = #{facet_repository}.repository_id",
             "INNER JOIN #{content_table} on #{content_table}.id = #{repo_join_table}.#{content_model.unit_id_field}",
             "INNER JOIN #{facet_join_table} on #{facet_join_table}.#{content_model.unit_id_field} = #{content_table}.id").
       where("#{facet_join_table}.content_facet_id = #{self.table_name}.id")
end

.joins_installable_rpmsObject



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

def self.joins_installable_rpms
  joins_installable_relation(Katello::Rpm, Katello::ContentFacetApplicableRpm)
end

.joins_repositoriesObject



282
283
284
285
286
287
288
289
290
291
292
# File 'app/models/katello/host/content_facet.rb', line 282

def self.joins_repositories
  facet_repository = Katello::ContentFacetRepository.table_name
  root_repository = Katello::RootRepository.table_name
  repository = Katello::Repository.table_name

  self.joins("INNER JOIN #{facet_repository} on #{facet_repository}.content_facet_id = #{table_name}.id",
             "INNER JOIN #{repository} on #{repository}.id = #{facet_repository}.repository_id",
             "INNER JOIN #{root_repository} on #{root_repository}.id = #{repository}.root_id",
             "INNER JOIN #{Katello::Content.table_name} on #{Katello::Content.table_name}.cp_content_id = #{root_repository}.content_id").
       where("#{facet_repository}.content_facet_id = #{self.table_name}.id")
end

.trigger_applicability_generation(host_ids) ⇒ Object



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

def self.trigger_applicability_generation(host_ids)
  host_ids = [host_ids] unless host_ids.is_a?(Array)
  ::Katello::ApplicableHostQueue.push_hosts(host_ids)
  ::Katello::EventQueue.push_event(::Katello::Events::GenerateHostApplicability::EVENT_TYPE, 0)
end

.with_applicable_errata(errata) ⇒ Object



262
263
264
# File 'app/models/katello/host/content_facet.rb', line 262

def self.with_applicable_errata(errata)
  self.joins(:applicable_errata).where("#{Katello::Erratum.table_name}.id" => errata)
end

.with_installable_errata(errata) ⇒ Object



266
267
268
# File 'app/models/katello/host/content_facet.rb', line 266

def self.with_installable_errata(errata)
  joins_installable_errata.where("#{Katello::Erratum.table_name}.id" => errata)
end

.with_non_installable_errata(errata, hosts = nil) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'app/models/katello/host/content_facet.rb', line 239

def self.with_non_installable_errata(errata, hosts = nil)
  content_facets = Katello::Host::ContentFacet.select(:id).where(:host_id => hosts)
  reachable_repos = ::Katello::ContentFacetRepository.where(content_facet_id: content_facets).distinct.pluck(:repository_id)
  installable_errata = ::Katello::ContentFacetErratum.select(:id).
    where(content_facet_id: content_facets).
    joins(
    "inner join #{::Katello::RepositoryErratum.table_name} ON #{Katello::ContentFacetErratum.table_name}.erratum_id = #{Katello::RepositoryErratum.table_name}.erratum_id",
    "inner JOIN #{Katello::ContentFacetRepository.table_name} "\
      "ON #{Katello::ContentFacetErratum.table_name}.content_facet_id = #{Katello::ContentFacetRepository.table_name}.content_facet_id "\
      "AND #{Katello::RepositoryErratum.table_name}.repository_id = #{Katello::ContentFacetRepository.table_name}.repository_id"
    ).
    where("#{Katello::RepositoryErratum.table_name}.repository_id" => reachable_repos).
    where("#{Katello::RepositoryErratum.table_name}.erratum_id" => errata).
    where("#{Katello::ContentFacetRepository.table_name}.repository_id" => reachable_repos).
    where("#{Katello::ContentFacetRepository.table_name}.content_facet_id" => content_facets)

  non_installable_errata = ::Katello::ContentFacetErratum.select(:content_facet_id).
    where.not(id: installable_errata).
    where(content_facet_id: content_facets, erratum_id: errata)

  Katello::Host::ContentFacet.where(id: non_installable_errata)
end

Instance Method Details

#assign_single_environment(content_view_id: nil, lifecycle_environment_id: nil, environment_id: nil, content_view: nil, lifecycle_environment: nil, environment: nil) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'app/models/katello/host/content_facet.rb', line 91

def assign_single_environment(
  content_view_id: nil, lifecycle_environment_id: nil, environment_id: nil,
  content_view: nil, lifecycle_environment: nil, environment: nil
)
  lifecycle_environment_id ||= environment_id || lifecycle_environment&.id || environment&.id
  content_view_id ||= content_view&.id

  unless lifecycle_environment_id
    fail _("Lifecycle environment must be specified")
  end

  unless content_view_id
    fail _("Content view must be specified")
  end

  content_view_environment = ::Katello::ContentViewEnvironment
    .where(:content_view_id => content_view_id, :environment_id => lifecycle_environment_id)
    .first_or_create do |cve|
    Rails.logger.info("ContentViewEnvironment not found for content view '#{cve.content_view_name}' and environment '#{cve.environment&.name}'; creating a new one.")
  end
  fail _("Unable to create ContentViewEnvironment. Check the logs for more information.") if content_view_environment.nil?
  self.content_view_environments = [content_view_environment]
end

#available_releasesObject



294
295
296
297
298
# File 'app/models/katello/host/content_facet.rb', line 294

def available_releases
  self.content_view_environments.flat_map do |cve|
    cve.content_view.version(cve.lifecycle_environment).available_releases
  end
end

#calculate_and_import_applicabilityObject

Katello applicability



193
194
195
196
197
198
199
200
201
202
203
204
# File 'app/models/katello/host/content_facet.rb', line 193

def calculate_and_import_applicability
  bound_repos = bound_repositories.collect do |repo|
    repo.library_instance_id.nil? ? repo.id : repo.library_instance_id
  end

  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::Deb, bound_repos).calculate_and_import
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::Rpm, bound_repos).calculate_and_import
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::Erratum, bound_repos).calculate_and_import
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::ModuleStream, bound_repos).calculate_and_import
  update_applicability_counts
  self.update_errata_status
end

#cves_changed?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'app/models/katello/host/content_facet.rb', line 63

def cves_changed?
  cves_changed
end

#default_environment?Boolean

Returns:

  • (Boolean)


115
116
117
118
119
# File 'app/models/katello/host/content_facet.rb', line 115

def default_environment?
  content_view_environments.any? do |cve|
    cve.content_view.default? && cve.lifecycle_environment.library?
  end
end

#errata_countsObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/katello/host/content_facet.rb', line 166

def errata_counts
  installable_hash = {
    :security => installable_security_errata_count,
    :bugfix => installable_bugfix_errata_count,
    :enhancement => installable_enhancement_errata_count
  }
  installable_hash[:total] = installable_hash.values.inject(:+)
  # same for applicable, but we need to get the counts from the db
  applicable_hash = {
    :security => applicable_errata.security.count,
    :bugfix => applicable_errata.bugfix.count,
    :enhancement => applicable_errata.enhancement.count
  }
  applicable_hash[:total] = applicable_hash.values.inject(:+)
  # keeping installable at the top level for backward compatibility
  installable_hash.merge({
                           :applicable => applicable_hash
                         })
end

#host_tools_installed?Boolean

Returns:

  • (Boolean)


314
315
316
317
318
319
320
321
# File 'app/models/katello/host/content_facet.rb', line 314

def host_tools_installed?
  host.installed_packages.where("#{Katello::InstalledPackage.table_name}.name" => [ "python-#{HOST_TOOLS_PACKAGE_NAME}",
                                                                                    "python3-#{HOST_TOOLS_PACKAGE_NAME}",
                                                                                    HOST_TOOLS_PACKAGE_NAME ]).any? ||
    host.installed_debs.where("#{Katello::InstalledDeb.table_name}.name" => [ "python-#{HOST_TOOLS_PACKAGE_NAME}",
                                                                              "python3-#{HOST_TOOLS_PACKAGE_NAME}",
                                                                              HOST_TOOLS_PACKAGE_NAME ]).any?
end

#installable_debs(env = nil, content_view = nil) ⇒ Object



154
155
156
# File 'app/models/katello/host/content_facet.rb', line 154

def installable_debs(env = nil, content_view = nil)
  Deb.installable_for_content_facet(self, env, content_view)
end

#installable_errata(env = nil, content_view = nil) ⇒ Object



150
151
152
# File 'app/models/katello/host/content_facet.rb', line 150

def installable_errata(env = nil, content_view = nil)
  Erratum.installable_for_content_facet(self, env, content_view)
end

#installable_module_streams(env = nil, content_view = nil) ⇒ Object



162
163
164
# File 'app/models/katello/host/content_facet.rb', line 162

def installable_module_streams(env = nil, content_view = nil)
  ModuleStream.installable_for_content_facet(self, env, content_view)
end

#installable_rpms(env = nil, content_view = nil) ⇒ Object



158
159
160
# File 'app/models/katello/host/content_facet.rb', line 158

def installable_rpms(env = nil, content_view = nil)
  Rpm.installable_for_content_facet(self, env, content_view)
end

#katello_agent_installed?Boolean

Returns:

  • (Boolean)


300
301
302
303
# File 'app/models/katello/host/content_facet.rb', line 300

def katello_agent_installed?
  self.host.installed_packages.where("#{Katello::InstalledPackage.table_name}.name" => 'katello-agent').any? ||
    self.host.installed_debs.where("#{Katello::InstalledDeb.table_name}.name" => 'katello-agent').any?
end

#mark_cves_changed(_cve) ⇒ Object



59
60
61
# File 'app/models/katello/host/content_facet.rb', line 59

def mark_cves_changed(_cve)
  self.cves_changed = true
end

#multi_content_view_environment?Boolean

Returns:

  • (Boolean)


67
68
69
70
# File 'app/models/katello/host/content_facet.rb', line 67

def multi_content_view_environment?
  # returns false if there are no content view environments
  content_view_environments.size > 1
end

#single_content_viewObject



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

def single_content_view
  if multi_content_view_environment?
    Rails.logger.warn _("Content facet for host %s has more than one content view. Use #content_views instead.") % host.name
  end
  content_view_environments&.first&.content_view
end

#single_content_view_environment?Boolean

Returns:

  • (Boolean)


72
73
74
75
# File 'app/models/katello/host/content_facet.rb', line 72

def single_content_view_environment?
  # also returns false if there are no content view environments
  content_view_environments.size == 1
end

#single_lifecycle_environmentObject



84
85
86
87
88
89
# File 'app/models/katello/host/content_facet.rb', line 84

def single_lifecycle_environment
  if multi_content_view_environment?
    Rails.logger.warn _("Content facet for host %s has more than one lifecycle environment. Use #lifecycle_environments instead.") % host.name
  end
  content_view_environments&.first&.lifecycle_environment
end

#tracer_installed?Boolean

Returns:

  • (Boolean)


305
306
307
308
309
310
311
312
# File 'app/models/katello/host/content_facet.rb', line 305

def tracer_installed?
  self.host.installed_packages.where("#{Katello::InstalledPackage.table_name}.name" => [ "python-#{HOST_TOOLS_TRACER_PACKAGE_NAME}",
                                                                                         "python3-#{HOST_TOOLS_TRACER_PACKAGE_NAME}",
                                                                                         HOST_TOOLS_TRACER_PACKAGE_NAME ]).any? ||
    self.host.installed_debs.where("#{Katello::InstalledDeb.table_name}.name" => [ "python-#{HOST_TOOLS_TRACER_PACKAGE_NAME}",
                                                                                   "python3-#{HOST_TOOLS_TRACER_PACKAGE_NAME}",
                                                                                   HOST_TOOLS_TRACER_PACKAGE_NAME ]).any?
end

#update_applicability_countsObject



206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'app/models/katello/host/content_facet.rb', line 206

def update_applicability_counts
  self.assign_attributes(
      :installable_security_errata_count => self.installable_errata.security.count,
      :installable_bugfix_errata_count => self.installable_errata.bugfix.count,
      :installable_enhancement_errata_count => self.installable_errata.enhancement.count,
      :applicable_deb_count => self.content_facet_applicable_debs.count,
      :upgradable_deb_count => self.installable_debs.count,
      :applicable_rpm_count => self.content_facet_applicable_rpms.count,
      :upgradable_rpm_count => self.installable_rpms.count,
      :applicable_module_stream_count => self.content_facet_applicable_module_streams.count,
      :upgradable_module_stream_count => self.installable_module_streams.count
  )
  self.save!(:validate => false)
end

#update_errata_statusObject



323
324
325
326
# File 'app/models/katello/host/content_facet.rb', line 323

def update_errata_status
  host.get_status(::Katello::ErrataStatus).refresh!
  host.refresh_global_status!
end

#update_repositories_by_paths(paths) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/katello/host/content_facet.rb', line 121

def update_repositories_by_paths(paths)
  prefixes = %w(/pulp/deb/ /pulp/repos/ /pulp/content/)
  relative_paths = []

  # paths == ["/pulp/content/Default_Organization/Library/custom/Test_product/test2"]
  paths.each do |path|
    if (prefix = prefixes.find { |pre| path.start_with?(pre) })
      relative_paths << path.gsub(prefix, '')
    else
      Rails.logger.warn("System #{self.host.name} (#{self.host.id}) requested binding to repo with unknown prefix. #{path}")
    end
  end

  repos = Repository.where(relative_path: relative_paths)
  relative_paths -= repos.pluck(:relative_path) # remove relative paths that match our repos

  # Any leftover relative paths do not match the repos we've just retrieved from the db,
  # so we should log warnings about them.
  relative_paths.each do |repo_path|
    Rails.logger.warn("System #{self.host.name} (#{self.host.id}) requested binding to unknown repo #{repo_path}")
  end

  unless self.bound_repositories.sort == repos.sort
    self.bound_repositories = repos
    self.save!
  end
  self.bound_repositories.pluck(:relative_path)
end