Class: Katello::ContentView

Inherits:
Model
  • Object
show all
Includes:
ForemanTasks::Concerns::ActionSubject, Authorization::ContentView, Ext::LabelFromName
Defined in:
app/models/katello/content_view.rb

Constant Summary collapse

CONTENT_DIR =
"content_views"

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Authorization::ContentView

#deletable?, #editable?, #promotable_or_removable?, #publishable?, #readable?

Methods included from Ext::LabelFromName

included, #label_not_changed, #setup_label_from_name

Methods inherited from Model

#destroy!

Class Method Details

.in_environment(env) ⇒ Object



69
70
71
72
# File 'app/models/katello/content_view.rb', line 69

def self.in_environment(env)
  joins(:content_view_environments).
    where("#{Katello::ContentViewEnvironment.table_name}.environment_id = ?", env.id)
end

Instance Method Details

#add_environment(env, version) ⇒ Object

Associate an environment with this content view. This can occur whenever a version of the view is promoted to an environment. It is necessary for candlepin to become aware that the view is available for consumers.



348
349
350
351
352
353
354
355
356
357
358
359
# File 'app/models/katello/content_view.rb', line 348

def add_environment(env, version)
  if self.content_view_environments.where(:environment_id => env.id).empty?
    label = generate_cp_environment_label(env)
    ContentViewEnvironment.create!(:name => label,
                                   :label => label,
                                   :cp_id => generate_cp_environment_id(env),
                                   :environment_id => env.id,
                                   :content_view => self,
                                   :content_view_version => version
                                  )
  end
end

#all_version_library_instancesObject

get the library instances of all repos within this view



267
268
269
270
271
# File 'app/models/katello/content_view.rb', line 267

def all_version_library_instances
  all_repos = all_version_repos.where(:library_instance_id => nil).pluck("#{Katello::Repository.table_name}.id")
  all_repos += all_version_repos.pluck(:library_instance_id)
  Repository.where(:id => all_repos)
end

#all_version_productsObject

list all products associated to this view across all versions



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

def all_version_products
  Product.joins(:repositories).where("#{Katello::Repository.table_name}.id" => self.all_version_repos).uniq
end

#all_version_reposObject



208
209
210
211
# File 'app/models/katello/content_view.rb', line 208

def all_version_repos
  Repository.joins(:content_view_version).
    where("#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
end

#as_json(options = {}) ⇒ Object

NOTE: this function will most likely become obsolete once we drop api v1



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'app/models/katello/content_view.rb', line 124

def as_json(options = {})
  result = self.attributes
  result['organization'] = self.organization.try(:name)
  result['environments'] = environments.map { |e| e.try(:name) }
  result['versions'] = versions.map(&:version)
  result['versions_details'] = versions.map do |v|
    {
      :version => v.version,
      :published => v.created_at.to_s,
      :environments => v.environments.map { |e| e.name }
    }
  end

  if options && options[:environment].present?
    result['repositories'] = repos(options[:environment]).map(&:name)
  end

  result
end

#build_puppet_env(options) ⇒ Object



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'app/models/katello/content_view.rb', line 393

def build_puppet_env(options)
  if options[:environment] && options[:version]
    fail "Cannot create into both an environment and a content view version archive"
  end

  to_env       = options[:environment]
  version      = options[:version]
  content_view = self
  to_version   = version || content_view.version(to_env)

  # Construct the pulp id using org/view/version or org/env/view
  pulp_id = ContentViewPuppetEnvironment.generate_pulp_id(organization.label, to_env.try(:label),
                                                          self.label, version.try(:version))

  ContentViewPuppetEnvironment.new(
    :environment => to_env,
    :content_view_version => to_version,
    :name => self.name,
    :pulp_id => pulp_id
  )
end

#check_composite_action_allowed!(env) ⇒ Object



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'app/models/katello/content_view.rb', line 460

def check_composite_action_allowed!(env)
  if composite? && Setting['restrict_composite_view']
    # verify that the composite's component view versions exist in the target environment.
    components.each do |component|
      unless component.environments.include?(env)
        fail _("The action requested on this composite view cannot be performed until all of the "\
               "component content view versions have been promoted to the target environment: %{env}.  "\
               "This restriction is optional and can be modified in the Administrator -> Settings "\
               "page using the restrict_composite_view flag.") %
               { :env => env.name }
      end
    end
  end
  true
end

#check_puppet_conflictsObject



327
328
329
330
331
332
333
334
# File 'app/models/katello/content_view.rb', line 327

def check_puppet_conflicts
  duplicate_puppet_modules.each do |name|
    versions = components.select { |v| v.puppet_modules.map(&:name).include?(name) }
    names = versions.map(&:name).join(", ")
    msg = _("Puppet module conflict: '%{mod}' is in %{versions}.") % {mod: name, versions: names}
    errors.add(:base, msg)
  end
end

#check_ready_to_destroy!Object



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'app/models/katello/content_view.rb', line 494

def check_ready_to_destroy!
  errors = []

  dependencies = {environments:           _("environments"),
                  systems:                _("systems"),
                  activation_keys:        _("activation keys")
  }

  dependencies.each do |key, name|
    if (models = self.association(key).scope).any?
      errors << _("Cannot delete '%{view}' due to associated %{dependent}: %{names}.") %
        {view: self.name, dependent: name, names: models.map(&:name).join(", ")}
    end
  end

  fail errors.join(" ") if errors.any?
  return true
end

#check_ready_to_publish!Object



453
454
455
456
457
458
# File 'app/models/katello/content_view.rb', line 453

def check_ready_to_publish!
  fail _("User must be logged in.") if ::User.current.nil?
  fail _("Cannot publish default content view") if default?
  check_composite_action_allowed!(organization.library)
  true
end

#check_remove_from_environment!(env) ⇒ Object



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
# File 'app/models/katello/content_view.rb', line 476

def check_remove_from_environment!(env)
  errors = []

  dependencies = {systems:                _("systems"),
                  activation_keys:        _("activation keys")
  }

  dependencies.each do |key, name|
    if (models = self.association(key).scope.in_environment(env)).any?
      errors << _("Cannot remove '%{view}' from environment '%{env}' due to associated %{dependent}: %{names}.") %
        {view: self.name, env: env.name, dependent: name, names: models.map(&:name).join(", ")}
    end
  end

  fail errors.join(" ") if errors.any?
  return true
end

#check_repo_conflictsObject



319
320
321
322
323
324
325
# File 'app/models/katello/content_view.rb', line 319

def check_repo_conflicts
  duplicate_repositories.each do |repo|
    versions = components.with_library_repo(repo).uniq.map(&:name).join(", ")
    msg = _("Repository conflict: '%{repo}' is in %{versions}.") % {repo: repo.name, versions: versions}
    errors.add(:base, msg)
  end
end

#component_modules_to_publishObject

Returns actual puppet modules associated with all components



227
228
229
# File 'app/models/katello/content_view.rb', line 227

def component_modules_to_publish
  composite? ? components.flat_map { |version| version.puppet_modules } : nil
end

#component_repositoriesObject



238
239
240
# File 'app/models/katello/content_view.rb', line 238

def component_repositories
  components.map(&:repositories).flatten
end

#computed_module_ids_by_repoidObject



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# File 'app/models/katello/content_view.rb', line 419

def computed_module_ids_by_repoid
  uuids = []
  names_and_authors = []
  puppet_modules = []

  if composite?
    uuids = component_modules_to_publish.collect { |puppet_module| puppet_module.uuid }
  else
    puppet_modules_to_publish.each do |cvpm|
      if cvpm.uuid
        uuids << cvpm.uuid
      else
        names_and_authors << { :name => cvpm.name, :author => cvpm.author }
      end
    end
  end

  puppet_modules = PuppetModule.where(:uuid => uuids) if uuids.present?

  if names_and_authors.present?
    names_and_authors.each do |name_and_author|
      puppet_module = ::Katello::PuppetModule.latest_module(
        name_and_author[:name],
        name_and_author[:author],
        self.organization.library.repositories.puppet_type
      )
      puppet_modules << puppet_module
    end
  end

  # In order to minimize the number of copy requests, organize the data by repoid.
  PuppetModule.group_by_repoid(puppet_modules)
end

#content_host_countObject



78
79
80
# File 'app/models/katello/content_view.rb', line 78

def content_host_count
  systems.count
end

#content_view_environment(environment) ⇒ Object



336
337
338
# File 'app/models/katello/content_view.rb', line 336

def content_view_environment(environment)
  self.content_view_environments.where(:environment_id => environment.try(:id)).first
end

#copy(new_name) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'app/models/katello/content_view.rb', line 82

def copy(new_name)
  new_view = ContentView.new
  new_view.name = new_name
  new_view.attributes = self.attributes.slice("description", "organization_id", "default", "composite")
  new_view.save!
  new_view.repositories = self.repositories
  new_view.components = self.components

  self.content_view_puppet_modules.each do |puppet_module|
    new_view.content_view_puppet_modules << puppet_module.dup
  end

  self.filters.each do |filter|
    new_filter = filter.dup
    new_filter.repositories = filter.repositories
    new_view.filters << new_filter

    case filter.type
    when ContentViewPackageFilter.name
      filter.package_rules.each do |rule|
        new_filter.package_rules << rule.dup
      end
    when ContentViewPackageGroupFilter.name
      filter.package_group_rules.each do |rule|
        new_filter.package_group_rules << rule.dup
      end
    when ContentViewErratumFilter.name
      filter.erratum_rules.each do |rule|
        new_filter.erratum_rules << rule.dup
      end
    end
  end
  new_view.save!
  new_view
end

#cp_environment_id(env) ⇒ Object



377
378
379
# File 'app/models/katello/content_view.rb', line 377

def cp_environment_id(env)
  ContentViewEnvironment.where(:content_view_id => self, :environment_id => env).first.try(:cp_id)
end

#cp_environment_label(env) ⇒ Object



373
374
375
# File 'app/models/katello/content_view.rb', line 373

def cp_environment_label(env)
  ContentViewEnvironment.where(:content_view_id => self, :environment_id => env).first.try(:label)
end

#create_new_version(description = '', major = next_version, minor = 0, components = self.components) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
# File 'app/models/katello/content_view.rb', line 381

def create_new_version(description = '', major = next_version, minor = 0, components = self.components)
  version = ContentViewVersion.create!(:major => major,
                                       :minor => minor,
                                       :content_view => self,
                                       :description => description,
                                       :components => components
                                      )

  increment!(:next_version) if minor == 0
  version
end

#create_puppet_env(options) ⇒ Object



415
416
417
# File 'app/models/katello/content_view.rb', line 415

def create_puppet_env(options)
  build_puppet_env(options).save!
end

#delete(from_env) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'app/models/katello/content_view.rb', line 280

def delete(from_env)
  if from_env.library? && in_non_library_environment?
    fail Errors::ChangesetContentException, _("Cannot delete view while it exists in environments")
  end

  version = self.version(from_env)
  if version.nil?
    fail Errors::ChangesetContentException, _("Cannot delete from %s, view does not exist there.") % from_env.name
  end
  version = ContentViewVersion.find(version.id)

  if foreman_env = Environment.find_by_katello_id(self.organization, from_env, self)
    foreman_env.destroy
  end

  version.delete(from_env)
  self.destroy if self.versions.empty?
end

#duplicate_puppet_modulesObject



311
312
313
314
315
316
317
# File 'app/models/katello/content_view.rb', line 311

def duplicate_puppet_modules
  modules = puppet_modules_to_publish || component_modules_to_publish
  counts = modules.each_with_object(Hash.new(0)) do |puppet_module, h|
    h[puppet_module.name] += 1
  end
  counts.select { |_k, v| v > 1 }.keys
end

#duplicate_repositoriesObject



303
304
305
306
307
308
309
# File 'app/models/katello/content_view.rb', line 303

def duplicate_repositories
  counts = repositories_to_publish.each_with_object(Hash.new(0)) do |repo, h|
    h[repo.library_instance_id] += 1
  end
  ids = counts.select { |_k, v| v > 1 }.keys
  Repository.where(:id => ids)
end

#get_repo_clone(env, repo) ⇒ Object



273
274
275
276
277
278
# File 'app/models/katello/content_view.rb', line 273

def get_repo_clone(env, repo)
  lib_id = repo.library_instance_id || repo.id
  Repository.in_environment(env).where(:library_instance_id => lib_id).
      joins(:content_view_version).
      where("#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
end

#historyObject



162
163
164
165
# File 'app/models/katello/content_view.rb', line 162

def history
  Katello::ContentViewHistory.joins(:content_view_version).where(
      "#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
end

#in_environment?(env) ⇒ Boolean

Returns:

  • (Boolean)


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

def in_environment?(env)
  environments.include?(env)
end

#in_non_library_environment?Boolean

Returns:

  • (Boolean)


299
300
301
# File 'app/models/katello/content_view.rb', line 299

def in_non_library_environment?
  environments.where(:library => false).length > 0
end

#library_repo_idsObject



204
205
206
# File 'app/models/katello/content_view.rb', line 204

def library_repo_ids
  repos(self.organization.library).map { |r| r.library_instance_id }
end

#library_reposObject



200
201
202
# File 'app/models/katello/content_view.rb', line 200

def library_repos
  Repository.where(:id => library_repo_ids)
end

#products(env = nil) ⇒ Object



251
252
253
254
# File 'app/models/katello/content_view.rb', line 251

def products(env = nil)
  repos = repos(env)
  Product.joins(:repositories).where("#{Katello::Repository.table_name}.id" => repos.map(&:id)).uniq
end

#promoted?Boolean

Returns:

  • (Boolean)


118
119
120
121
# File 'app/models/katello/content_view.rb', line 118

def promoted?
  # if the view exists in more than 1 environment, it has been promoted
  self.environments.length > 1 ? true : false
end

#puppet_env(env) ⇒ Object



191
192
193
194
195
196
197
198
# File 'app/models/katello/content_view.rb', line 191

def puppet_env(env)
  if env
    ids = versions.flat_map { |version| version.content_view_puppet_environments.in_environment(env) }.map(&:id)
  else
    ids = []
  end
  ContentViewPuppetEnvironment.where(:id => ids).first
end

#puppet_modules_to_publishObject

Returns the content view puppet modules associated with the content view



234
235
236
# File 'app/models/katello/content_view.rb', line 234

def puppet_modules_to_publish
  composite? ? nil : content_view_puppet_modules
end

#puppet_reposObject



177
178
179
180
# File 'app/models/katello/content_view.rb', line 177

def puppet_repos
  # These are the repos that may contain puppet modules that can be associated with the content view
  self.organization.library.repositories.puppet_type
end

#remove_environment(env) ⇒ Object

Unassociate an environment from this content view. This can occur whenever a view is deleted from an environment. It is necessary to make candlepin aware that the view is no longer available for consumers.



364
365
366
367
368
369
370
371
# File 'app/models/katello/content_view.rb', line 364

def remove_environment(env)
  # Do not remove the content view environment, if there is still a view
  # version in the environment.
  if self.versions.in_environment(env).blank?
    view_env = self.content_view_environments.where(:environment_id => env.id)
    view_env.first.destroy unless view_env.blank?
  end
end

#repos(env = nil) ⇒ Object



182
183
184
185
186
187
188
189
# File 'app/models/katello/content_view.rb', line 182

def repos(env = nil)
  if env
    repo_ids = versions.flat_map { |version| version.repositories.in_environment(env) }.map(&:id)
  else
    repo_ids = versions.flat_map { |version| version.repositories }.map(&:id)
  end
  Repository.where(:id => repo_ids)
end

#repos_in_product(env, product) ⇒ Object



242
243
244
245
246
247
248
249
# File 'app/models/katello/content_view.rb', line 242

def repos_in_product(env, product)
  version = version(env)
  if version
    version.repositories.in_environment(env).in_product(product)
  else
    []
  end
end

#repositories_to_publishObject



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

def repositories_to_publish
  if composite?
    ids = components.flat_map { |version| version.repositories.archived }.map(&:id)
    Repository.where(:id => ids)
  else
    repositories
  end
end

#repositories_to_publish_idsObject



222
223
224
# File 'app/models/katello/content_view.rb', line 222

def repositories_to_publish_ids
  composite? ? repositories_to_publish.pluck(&:id) : repository_ids
end

#resulting_productsObject



173
174
175
# File 'app/models/katello/content_view.rb', line 173

def resulting_products
  (self.repositories.collect { |r| r.product }).uniq
end

#to_sObject



74
75
76
# File 'app/models/katello/content_view.rb', line 74

def to_s
  name
end

#total_package_count(env) ⇒ Object



144
145
146
# File 'app/models/katello/content_view.rb', line 144

def total_package_count(env)
  Katello::Rpm.in_repositories(self.repos(env)).count
end

#total_puppet_module_count(env) ⇒ Object



148
149
150
151
152
# File 'app/models/katello/content_view.rb', line 148

def total_puppet_module_count(env)
  repoids = self.repos(env).collect { |r| r.pulp_id }
  result = Katello::PuppetModule.legacy_search('*', :page_size => 1, :repoids => repoids)
  result.length > 0 ? result.total : 0
end

#update_cp_content(env) ⇒ Object



340
341
342
343
# File 'app/models/katello/content_view.rb', line 340

def update_cp_content(env)
  view_env = content_view_environment(env)
  view_env.update_cp_content if view_env
end

#version(env) ⇒ Object



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

def version(env)
  self.versions.in_environment(env).order("#{Katello::ContentViewVersion.table_name}.id ASC").readonly(false).last
end

#version_environment(env) ⇒ Object



167
168
169
170
171
# File 'app/models/katello/content_view.rb', line 167

def version_environment(env)
  # TODO: rewrite this into SQL or use content_view_environment when that
  # points to environment
  version(env).content_view_version_environments.select { |cvve| cvve.environment_id == env.id }
end

#version_products(env) ⇒ Object



256
257
258
259
# File 'app/models/katello/content_view.rb', line 256

def version_products(env)
  repos = repos(env)
  Product.joins(:repositories).where("#{Katello::Repository.table_name}.id" => repos.map(&:id)).uniq
end