Class: Katello::RootRepository

Inherits:
Model
  • Object
show all
Includes:
Encryptable, Ext::LabelFromName
Defined in:
app/models/katello/root_repository.rb

Overview

rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: Jail

Constant Summary collapse

DOWNLOAD_IMMEDIATE =
'immediate'.freeze
DOWNLOAD_ON_DEMAND =
'on_demand'.freeze
DOWNLOAD_POLICIES =
[DOWNLOAD_IMMEDIATE, DOWNLOAD_ON_DEMAND].freeze
IGNORABLE_CONTENT_UNIT_TYPES =
%w(srpm treeinfo).freeze
CHECKSUM_TYPES =
%w(sha256 sha384 sha512).freeze
SUBSCRIBABLE_TYPES =
[Repository::YUM_TYPE, Repository::OSTREE_TYPE, Repository::DEB_TYPE].freeze
SKIPABLE_METADATA_TYPES =
[Repository::YUM_TYPE, Repository::DEB_TYPE].freeze
CONTENT_ATTRIBUTE_RESTRICTIONS =
{
  :download_policy => [Repository::YUM_TYPE, Repository::DEB_TYPE, Repository::DOCKER_TYPE, Repository::FILE_TYPE],
}.freeze
MAX_EXPIRE_TIME =
7 * 24 * 60 * 60
NO_DEFAULT_HTTP_PROXY =
'none'.freeze
GLOBAL_DEFAULT_HTTP_PROXY =
'global_default_http_proxy'.freeze
USE_SELECTED_HTTP_PROXY =
'use_selected_http_proxy'.freeze
HTTP_PROXY_POLICIES =
[
GLOBAL_DEFAULT_HTTP_PROXY,
NO_DEFAULT_HTTP_PROXY,
USE_SELECTED_HTTP_PROXY].freeze
RHEL6 =
'rhel-6'.freeze
RHEL7 =
'rhel-7'.freeze
RHEL8 =
'rhel-8'.freeze
RHEL9 =
'rhel-9'.freeze
RHEL10 =
'rhel-10'.freeze
ALLOWED_OS_VERSIONS =
[RHEL6, RHEL7, RHEL8, RHEL9, RHEL10].freeze
MIRRORING_POLICY_ADDITIVE =
'additive'.freeze
MIRRORING_POLICY_CONTENT =
'mirror_content_only'.freeze
MIRRORING_POLICY_COMPLETE =
'mirror_complete'.freeze
MIRRORING_POLICIES =
[MIRRORING_POLICY_ADDITIVE, MIRRORING_POLICY_COMPLETE, MIRRORING_POLICY_CONTENT].freeze
NON_YUM_MIRRORING_POLICIES =
[MIRRORING_POLICY_ADDITIVE, MIRRORING_POLICY_CONTENT].freeze
ALLOWED_UPDATE_FIELDS =
['updated_at', 'content_id'].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Ext::LabelFromName

included, #label_not_changed, #setup_label_from_name

Methods inherited from Model

#destroy!

Class Method Details

.hosts_with_applicabilityObject



219
220
221
# File 'app/models/katello/root_repository.rb', line 219

def self.hosts_with_applicability
  ::Host.joins(:content_facet => :bound_repositories).where("#{Katello::Repository.table_name}.root_id" => self.select(:id))
end

.in_organization(org) ⇒ Object



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

def self.in_organization(org)
  joins(:product).where("#{Katello::Product.table_name}.organization_id" => org)
end

.repositoriesObject



151
152
153
# File 'app/models/katello/root_repository.rb', line 151

def self.repositories
  Repository.where(:root => self)
end

Instance Method Details

#allow_updates?(additional_allowed_fields = []) ⇒ Boolean

Returns:

  • (Boolean)


453
454
455
456
457
458
459
460
461
462
463
# File 'app/models/katello/root_repository.rb', line 453

def allow_updates?(additional_allowed_fields = [])
  # allow updates for non-container-push repos, repos not in default view, and
  # repos with a library instance
  return true unless is_container_push && library_instance.present?

  # let updates that contain ONLY allowed strings through
  allowed_fields = ::Katello::RootRepository::ALLOWED_UPDATE_FIELDS + additional_allowed_fields
  return true if (changed - allowed_fields).empty?

  false
end

#ansible_collection?Boolean

Returns:

  • (Boolean)


392
393
394
# File 'app/models/katello/root_repository.rb', line 392

def ansible_collection?
  self.content_type == Repository::ANSIBLE_COLLECTION_TYPE
end

#calculate_updated_nameObject



422
423
424
425
# File 'app/models/katello/root_repository.rb', line 422

def calculate_updated_name
  fail _("Cannot calculate name for custom repos") if custom?
  repo_mapper.name
end

#custom?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'app/models/katello/root_repository.rb', line 159

def custom?
  !redhat?
end

#custom_content_labelObject



368
369
370
# File 'app/models/katello/root_repository.rb', line 368

def 
  "#{organization.label} #{product.label} #{label}".gsub(/\s/, "_")
end

#custom_content_pathObject



357
358
359
360
361
362
363
364
365
366
# File 'app/models/katello/root_repository.rb', line 357

def custom_content_path
  parts = []
  # We generate repo path only for custom product content. We add this
  # constant string to avoid collisions with RH content. RH content url
  # begins usually with something like "/content/dist/rhel/...".
  # There we prefix custom content/repo url with "/custom/..."
  parts << "custom"
  parts += [product.label, self.label]
  "/" + parts.map { |x| x.gsub(/[^-\w]/, "_") }.join("/")
end

#deb?Boolean

Returns:

  • (Boolean)


388
389
390
# File 'app/models/katello/root_repository.rb', line 388

def deb?
  self.content_type == Repository::DEB_TYPE
end

#docker?Boolean

Returns:

  • (Boolean)


372
373
374
# File 'app/models/katello/root_repository.rb', line 372

def docker?
  self.content_type == Repository::DOCKER_TYPE
end

#ensure_compatible_download_policyObject



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

def ensure_compatible_download_policy
  if !url.blank? && URI(url).scheme == 'file' &&
      download_policy == ::Katello::RootRepository::DOWNLOAD_ON_DEMAND
    errors.add(:download_policy, _("Cannot sync file:// repositories with the On Demand Download Policy"))
  end
end

#ensure_content_attribute_restrictionsObject



175
176
177
178
179
180
181
# File 'app/models/katello/root_repository.rb', line 175

def ensure_content_attribute_restrictions
  CONTENT_ATTRIBUTE_RESTRICTIONS.each do |attribute, value|
    if self.send(attribute).present? && !value.include?(self.content_type)
      errors.add(attribute, _("Cannot set attribute %{attr} for content type %{type}") % {:attr => attribute, :type => self.content_type})
    end
  end
end

#ensure_docker_repo_unprotectedObject



212
213
214
215
216
217
# File 'app/models/katello/root_repository.rb', line 212

def ensure_docker_repo_unprotected
  unless unprotected
    errors.add(:base, _("Container Image Repositories are not protected at this time. " \
                        "They need to be published via http to be available to containers."))
  end
end

#ensure_metadata_expire_validObject



350
351
352
353
354
355
# File 'app/models/katello/root_repository.rb', line 350

def 
  return if self..blank?
  unless yum? && custom?
    errors.add(:metadata_expire, N_("It is only allowed for Non-Redhat Yum repositories."))
  end
end

#ensure_no_checksum_on_demandObject



223
224
225
226
227
# File 'app/models/katello/root_repository.rb', line 223

def ensure_no_checksum_on_demand
  if checksum_type.present? && download_policy == DOWNLOAD_ON_DEMAND
    errors.add(:checksum_type, _("Checksum type cannot be set for yum repositories with on demand download policy."))
  end
end

#ensure_valid_auth_url_tokenObject



310
311
312
313
314
315
316
317
318
319
320
# File 'app/models/katello/root_repository.rb', line 310

def ensure_valid_auth_url_token
  if self.ansible_collection_auth_url.blank? && self.ansible_collection_auth_token.blank?
    self.ansible_collection_auth_url = nil
    self.ansible_collection_auth_token = nil
    return
  end

  if !self.ansible_collection_auth_url.blank? && self.ansible_collection_auth_token.blank?
    errors.add(:base, N_("Auth URL requires Auth token be set."))
  end
end

#ensure_valid_authentication_tokenObject



322
323
324
325
326
# File 'app/models/katello/root_repository.rb', line 322

def ensure_valid_authentication_token
  if self.upstream_authentication_token.blank?
    self.upstream_authentication_token = nil
  end
end

#ensure_valid_collection_attributesObject



229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'app/models/katello/root_repository.rb', line 229

def ensure_valid_collection_attributes
  errors.add(:base, _("URL needs to have a trailing /")) if !url.blank? && url[-1] != '/'
  return unless ansible_collection_requirements
  begin
    requirements = YAML.safe_load(ansible_collection_requirements)
    if requirements.is_a?(Hash)
      errors.add(:base,  _("Requirements yaml should have a 'collections' key")) unless requirements.key?('collections')
    else
      errors.add(:base,  _('Requirements yaml should be a key-value pair structure.'))
    end
  rescue
    errors.add(:base, _('Requirements is not valid yaml.'))
  end
end

#ensure_valid_deb_constraintsObject



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

def ensure_valid_deb_constraints
  return if self.deb_releases.blank? && self.url.blank?
  if self.deb_releases.blank?
    errors.add(:base, N_("When \"Upstream URL\" is set, \"Releases/Distributions\" must also be set!"))
  elsif self.url.blank?
    errors.add(:base, N_("When \"Releases/Distributions\" is set, \"Upstream URL\" must also be set!"))
  end
end

#ensure_valid_docker_attributesObject



205
206
207
208
209
210
# File 'app/models/katello/root_repository.rb', line 205

def ensure_valid_docker_attributes
  if (!url.blank? && docker_upstream_name.blank?)
    errors.add(:docker_upstream_name, N_("cannot be blank when Repository URL is provided."))
    errors.add(:base, _("Upstream Name cannot be blank when Repository URL is provided."))
  end
end

#ensure_valid_exclude_tagsObject



264
265
266
267
268
269
# File 'app/models/katello/root_repository.rb', line 264

def ensure_valid_exclude_tags
  return if exclude_tags.blank?
  unless exclude_tags.is_a?(Array)
    errors.add(:exclude_tags, N_("Invalid value specified for Container Image repositories."))
  end
end

#ensure_valid_ignorable_contentObject



244
245
246
247
248
249
250
251
252
253
254
255
# File 'app/models/katello/root_repository.rb', line 244

def ensure_valid_ignorable_content
  return if ignorable_content.blank?
  if !yum?
    errors.add(:ignorable_content, N_("Ignorable content can be only set for Yum repositories."))
  elsif !ignorable_content.is_a?(Array)
    errors.add(:ignorable_content, N_("Invalid value specified for ignorable content."))
  elsif ignorable_content.any? { |item| !IGNORABLE_CONTENT_UNIT_TYPES.include?(item) }
    errors.add(:ignorable_content, N_("Invalid value specified for ignorable content. Permissible values %s") % IGNORABLE_CONTENT_UNIT_TYPES.join(","))
  elsif self.mirroring_policy == MIRRORING_POLICY_COMPLETE
    errors.add(:ignorable_content, N_("Ignore %s cannot be set in combination with the 'Complete Mirroring' mirroring policy.") % ignorable_content)
  end
end

#ensure_valid_include_tagsObject



257
258
259
260
261
262
# File 'app/models/katello/root_repository.rb', line 257

def ensure_valid_include_tags
  return if include_tags.blank?
  unless include_tags.is_a?(Array)
    errors.add(:include_tags, N_("Invalid value specified for Container Image repositories."))
  end
end

#ensure_valid_mirroring_policyObject



198
199
200
201
202
203
# File 'app/models/katello/root_repository.rb', line 198

def ensure_valid_mirroring_policy
  unless valid_mirroring_policies.include?(self.mirroring_policy)
    errors.add(:mirroring_policy, _("Invalid mirroring policy for repository type %{type}, only %{policies} are valid.") %
      {:type => self.content_type, :policies => valid_mirroring_policies.join(', ')})
  end
end

#ensure_valid_os_versionsObject



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'app/models/katello/root_repository.rb', line 271

def ensure_valid_os_versions
  return if os_versions.empty?
  # os_versions here translate to candlepin as 'required tags'.
  # A host must provide ALL required tags in order for the repo to be enabled.
  # So os_versions such as ['rhel-7', 'rhel-8'] is not allowed, since the repo would always be disabled.
  unless yum?
    errors.add(:os_versions, N_("are only allowed for Yum repositories."))
  end
  if os_versions.length > 1
    errors.add(:os_versions, N_("invalid: Repositories can only require one OS version."))
  end
  os_versions.each do |tag|
    unless ALLOWED_OS_VERSIONS.include?(tag)
      errors.add(:os_versions, N_("must be one of: %s" % ALLOWED_OS_VERSIONS.join(', ')))
    end
  end
end

#ensure_valid_retain_package_versions_countObject



337
338
339
340
341
342
343
344
345
346
347
348
# File 'app/models/katello/root_repository.rb', line 337

def ensure_valid_retain_package_versions_count
  return unless self.retain_package_versions_count
  unless yum?
    errors.add(:retain_package_versions_count, N_("is only allowed for Yum repositories."))
  end
  if yum? && self.mirroring_policy != MIRRORING_POLICY_ADDITIVE
    errors.add(:retain_package_versions_count, N_("cannot be set for repositories without 'Additive' mirroring policy."))
  end
  if self.retain_package_versions_count.to_i < 0
    errors.add(:retain_package_versions_count, N_("must not be a negative value."))
  end
end

#ensure_valid_upstream_authorizationObject



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'app/models/katello/root_repository.rb', line 289

def ensure_valid_upstream_authorization
  # Make sure that the upstream_username / upstream_password is really unset
  # in case if the string is maybe just ""
  if self.upstream_username.blank? && self.upstream_password.blank?
    self.upstream_username = nil
    self.upstream_password = nil
    if !self.url.blank? && self.url.start_with?('uln')
      errors.add(:base, N_("Upstream username and upstream password cannot be blank for ULN repositories"))
    end
    return
  end

  if redhat?
    errors.add(:base, N_("Upstream username and password may only be set on custom repositories."))
  elsif self.upstream_username.blank?
    errors.add(:base, N_("Upstream password requires upstream username be set."))
  elsif !self.upstream_password
    errors.add(:base, N_("Upstream username requires upstream password be set.")) # requirement of pulp
  end
end

#file?Boolean

Returns:

  • (Boolean)


376
377
378
# File 'app/models/katello/root_repository.rb', line 376

def file?
  self.content_type == Repository::FILE_TYPE
end

#format_archesObject



444
445
446
447
448
449
450
451
# File 'app/models/katello/root_repository.rb', line 444

def format_arches
  if self.deb?
    # Pulp 2 needed a "," separated string-list, but Pulp 3 needs " " separated!
    self.deb_architectures&.gsub(" ", ",")
  else
    self.arch == "noarch" ? nil : self.arch
  end
end

#generic?Boolean

Returns:

  • (Boolean)


396
397
398
# File 'app/models/katello/root_repository.rb', line 396

def generic?
  Katello::RepositoryTypeManager.generic_repository_types(false).values.map(&:id).map(&:to_s).flatten.include? self.content_type
end

#http_proxyObject



434
435
436
437
438
439
440
441
442
# File 'app/models/katello/root_repository.rb', line 434

def http_proxy
  case http_proxy_policy
  when NO_DEFAULT_HTTP_PROXY
    return nil
  when GLOBAL_DEFAULT_HTTP_PROXY
    return HttpProxy.default_global_content_proxy
  end
  super
end

#library_instanceObject



147
148
149
# File 'app/models/katello/root_repository.rb', line 147

def library_instance
  repositories.in_default_view.first
end

#on_demand?Boolean

Returns:

  • (Boolean)


404
405
406
# File 'app/models/katello/root_repository.rb', line 404

def on_demand?
  self.download_policy == DOWNLOAD_ON_DEMAND
end

#ostree?Boolean

Returns:

  • (Boolean)


384
385
386
# File 'app/models/katello/root_repository.rb', line 384

def ostree?
  self.content_type == Repository::OSTREE_TYPE
end

#prevent_updatesObject



465
466
467
# File 'app/models/katello/root_repository.rb', line 465

def prevent_updates
  fail _("Cannot update properties of a container push repository")
end

#pulp_update_needed?Boolean

Returns:

  • (Boolean)


408
409
410
411
412
413
414
415
416
# File 'app/models/katello/root_repository.rb', line 408

def pulp_update_needed?
  changeable_attributes = %w(url unprotected checksum_type docker_upstream_name download_policy verify_ssl_on_sync
                             upstream_username upstream_password retain_package_versions_count
                             ssl_ca_cert_id ssl_client_cert_id ssl_client_key_id http_proxy_policy http_proxy_id download_concurrency)
  changeable_attributes += %w(name container_repository_name include_tags exclude_tags) if docker?
  changeable_attributes += %w(deb_releases deb_components deb_architectures gpg_key_id) if deb?
  changeable_attributes += %w(ansible_collection_requirements ansible_collection_auth_url ansible_collection_auth_token) if ansible_collection?
  changeable_attributes.any? { |key| previous_changes.key?(key) }
end

#remove_sha1_checksum_typeObject



171
172
173
# File 'app/models/katello/root_repository.rb', line 171

def remove_sha1_checksum_type
  self.checksum_type = nil
end

#repo_mapperObject



418
419
420
# File 'app/models/katello/root_repository.rb', line 418

def repo_mapper
  @repo_mapper ||= Katello::Candlepin::RepositoryMapper.new(self.product, self.library_instance.content, self.substitutions)
end

#repository_typeObject



155
156
157
# File 'app/models/katello/root_repository.rb', line 155

def repository_type
  RepositoryTypeManager.find(self.content_type)
end

#sha1_checksum?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'app/models/katello/root_repository.rb', line 167

def sha1_checksum?
  checksum_type == 'sha1'
end

#substitutionsObject



427
428
429
430
431
432
# File 'app/models/katello/root_repository.rb', line 427

def substitutions
  {
    :releasever => self.minor,
    :basearch => self.arch,
  }.compact
end

#using_mirrored_content?Boolean

Returns:

  • (Boolean)


400
401
402
# File 'app/models/katello/root_repository.rb', line 400

def using_mirrored_content?
  self.mirroring_policy != Katello::RootRepository::MIRRORING_POLICY_ADDITIVE
end

#valid_mirroring_policiesObject



190
191
192
193
194
195
196
# File 'app/models/katello/root_repository.rb', line 190

def valid_mirroring_policies
  if self.yum?
    MIRRORING_POLICIES
  else
    [MIRRORING_POLICY_ADDITIVE, MIRRORING_POLICY_CONTENT]
  end
end

#yum?Boolean

Returns:

  • (Boolean)


380
381
382
# File 'app/models/katello/root_repository.rb', line 380

def yum?
  self.content_type == Repository::YUM_TYPE
end