Module: Katello::Concerns::SmartProxyExtensions

Extended by:
ActiveSupport::Concern
Defined in:
app/models/katello/concerns/smart_proxy_extensions.rb

Overview

rubocop:disable Metrics/ModuleLength

Defined Under Namespace

Modules: Overrides

Constant Summary collapse

PULP3_FEATURE =
"Pulpcore".freeze
PULP_FEATURE =
"Pulp".freeze
PULP_NODE_FEATURE =
"Pulp Node".freeze
CONTAINER_GATEWAY_FEATURE =
"Container_Gateway".freeze
DOWNLOAD_INHERIT =
'inherit'.freeze
DOWNLOAD_STREAMED =
'streamed'.freeze
DOWNLOAD_POLICIES =
[::Katello::RootRepository::DOWNLOAD_ON_DEMAND, ::Katello::RootRepository::DOWNLOAD_IMMEDIATE, DOWNLOAD_INHERIT, DOWNLOAD_STREAMED].freeze

Instance Method Summary collapse

Instance Method Details

#active_sync_tasksObject



382
383
384
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 382

def active_sync_tasks
  sync_tasks.where(:result => 'pending')
end

#add_lifecycle_environment(environment) ⇒ Object



359
360
361
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 359

def add_lifecycle_environment(environment)
  self.lifecycle_environments << environment
end

#alternate_content_sourcesObject



120
121
122
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 120

def alternate_content_sources
  SmartProxy.joins(:smart_proxy_alternate_content_sources).where('katello_smart_proxy_alternate_content_sources.smart_proxy_id' => self.id)
end

#associate_default_locationsObject



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

def associate_default_locations
  return unless self.pulp_primary?
  default_location = ::Location.unscoped.find_by_title(
    ::Setting[:default_location_subscribed_hosts])
  if default_location.present? && !locations.include?(default_location)
    self.locations << default_location
  end
end

#associate_lifecycle_environmentsObject



355
356
357
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 355

def associate_lifecycle_environments
  self.lifecycle_environments = Katello::KTEnvironment.all if self.pulp_primary?
end

#associate_organizationsObject



324
325
326
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 324

def associate_organizations
  self.organizations = Organization.all if self.pulp_primary?
end

#audit_capsule_syncObject



462
463
464
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 462

def audit_capsule_sync
  write_audit(action: "sync capsule", comment: _('Successfully synced capsule.'), audited_changes: {})
end

#available_lifecycle_environments(organization_id = nil) ⇒ Object



372
373
374
375
376
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 372

def available_lifecycle_environments(organization_id = nil)
  scope = Katello::KTEnvironment.not_in_capsule(self)
  scope = scope.where(organization_id: organization_id) if organization_id
  scope
end

#cancel_syncObject



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

def cancel_sync
  active_sync_tasks.map(&:cancel)
end

#container_gateway_usersObject



170
171
172
173
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 170

def container_gateway_users
  usernames = ProxyAPI::ContainerGateway.new(url: self.url).users
  ::User.where(login: usernames['users'])
end

#content_service(content_type) ⇒ Object



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

def content_service(content_type)
  if content_type.is_a?(String)
    content_type_obj = RepositoryTypeManager.find_content_type(content_type)
  else
    content_type_obj = content_type
  end
  content_type_string = content_type_obj&.label || content_type
  unless content_type_obj
    fail _("Content type %{content_type_string} does not belong to an enabled repo type.") %
           { content_type_string: content_type_string }
  end
  content_type_obj.pulp3_service_class
end

#current_repositories_data(environment = nil, content_view = nil) ⇒ Object



437
438
439
440
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 437

def current_repositories_data(environment = nil, content_view = nil)
  return repos_in_sync_history unless (environment || content_view)
  repos_in_sync_history & repos_in_env_cv(environment, content_view)
end

#environment_syncable?(env) ⇒ Boolean



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

def environment_syncable?(env)
  last_sync_time.nil? || env.content_view_environments.where('updated_at > ?', last_sync_time).any?
end

#fix_pulp3_capabilities(type) ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 250

def fix_pulp3_capabilities(type)
  if type.is_a?(String) || type.is_a?(Symbol)
    repository_type_obj = Katello::RepositoryTypeManager.defined_repository_types[type]
  else
    repository_type_obj = type
  end

  if missing_pulp3_capabilities? && repository_type_obj.pulp3_plugin
    self.refresh
    if self.capabilities(::SmartProxy::PULP3_FEATURE).empty?
      fail Katello::Errors::PulpcoreMissingCapabilities
    end
  end
end

#last_failed_sync_tasksObject



386
387
388
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 386

def last_failed_sync_tasks
  sync_tasks.where('started_at > ?', last_sync_time).where.not(:result => 'pending')
end

#last_sync_auditObject



390
391
392
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 390

def last_sync_audit
  Audited::Audit.where(:auditable_id => self, :auditable_type => SmartProxy.name, action: "sync capsule").order(:created_at).last
end

#last_sync_timeObject



394
395
396
397
398
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 394

def last_sync_time
  task = sync_tasks.where.not(:ended_at => nil).where(:result => 'success').order(:ended_at).last

  task&.ended_at || last_sync_audit&.created_at&.to_s
end

#missing_pulp3_capabilities?Boolean



246
247
248
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 246

def missing_pulp3_capabilities?
  pulp3_enabled? && self.capabilities(PULP3_FEATURE).empty?
end

#ping_pulpObject



408
409
410
411
412
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 408

def ping_pulp
  ::Katello::Ping.pulp_without_auth(self.pulp_url)
rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED, RestClient::Exception => error
  raise ::Katello::Errors::CapsuleCannotBeReached, _("%s is unreachable. %s" % [self.name, error])
end

#ping_pulp3Object



414
415
416
417
418
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 414

def ping_pulp3
  ::Katello::Ping.pulp3_without_auth(self.pulp3_url)
rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED, RestClient::Exception => error
  raise ::Katello::Errors::CapsuleCannotBeReached, _("%s is unreachable. %s" % [self.name, error])
end

#pulp3_configuration(config_class) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 184

def pulp3_configuration(config_class)
  config_class.new do |config|
    uri = pulp3_uri!
    config.host = uri.host
    config.scheme = uri.scheme
    pulp3_ssl_configuration(config)
    config.debugging = ::Foreman::Logging.logger('katello/pulp_rest').debug?
    config.timeout = SETTINGS[:katello][:rest_client_timeout]
    config.logger = ::Foreman::Logging.logger('katello/pulp_rest')
    config.username = self.setting(PULP3_FEATURE, 'username')
    config.password = self.setting(PULP3_FEATURE, 'password')
  end
end

#pulp3_content_support?(content_type) ⇒ Boolean



275
276
277
278
279
280
281
282
283
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 275

def pulp3_content_support?(content_type)
  content_type_obj = content_type.is_a?(String) ? Katello::RepositoryTypeManager.find_content_type(content_type) : content_type
  content_type_string = content_type_obj&.label || content_type
  fail "Content type #{content_type_string} does not belong to an enabled repo type." unless content_type_obj

  found_type = Katello::RepositoryTypeManager.enabled_repository_types.values.find { |repo_type| repo_type.content_types.include?(content_type_obj) }
  fail "Cannot find repository type for content_type #{content_type}, is it enabled?" unless found_type
  pulp3_repository_type_support?(found_type)
end

#pulp3_enabled?Boolean



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

def pulp3_enabled?
  self.has_feature? PULP3_FEATURE
end

#pulp3_host!Object



291
292
293
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 291

def pulp3_host!
  pulp3_uri!.host
end

#pulp3_repository_type_support?(repository_type) ⇒ Boolean



265
266
267
268
269
270
271
272
273
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 265

def pulp3_repository_type_support?(repository_type)
  repository_type_obj = repository_type.is_a?(String) ? Katello::RepositoryTypeManager.find(repository_type) : repository_type
  fail "Cannot find repository type #{repository_type}, is it enabled?" unless repository_type_obj

  repository_type_obj.pulp3_plugin.present? &&
    pulp3_enabled? &&
    (self.capabilities(PULP3_FEATURE).try(:include?, repository_type_obj.pulp3_plugin) ||
      self.capabilities(PULP3_FEATURE).try(:include?, 'pulp_' + repository_type_obj.pulp3_plugin))
end

#pulp3_ssl_configuration(config, connection_adapter = Faraday.default_adapter) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 198

def pulp3_ssl_configuration(config, connection_adapter = Faraday.default_adapter)
  if connection_adapter == :excon
    config.ssl_client_cert = ::Cert::Certs.ssl_client_cert_filename
    config.ssl_client_key = ::Cert::Certs.ssl_client_key_filename
  elsif connection_adapter == :net_http
    config.ssl_client_cert = ::Cert::Certs.ssl_client_cert
    config.ssl_client_key = ::Cert::Certs.ssl_client_key
  else
    fail "Unexpected connection_adapter #{Faraday.default_adapter}!  Cannot continue, this is likely a bug."
  end
end

#pulp3_support?(repository) ⇒ Boolean



242
243
244
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 242

def pulp3_support?(repository)
  repository ? pulp3_repository_type_support?(repository.try(:content_type)) : false
end

#pulp3_uri!Object



285
286
287
288
289
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 285

def pulp3_uri!
  url = self.setting(PULP3_FEATURE, 'pulp_url')
  fail "Cannot determine pulp3 url, check smart proxy configuration" unless url
  URI.parse(url)
end

#pulp3_url(path = '/pulp/api/v3') ⇒ Object



295
296
297
298
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 295

def pulp3_url(path = '/pulp/api/v3')
  pulp_url = self.setting(PULP3_FEATURE, 'pulp_url')
  path.blank? ? pulp_url : "#{pulp_url.sub(%r|/$|, '')}/#{path.sub(%r|^/|, '')}"
end

#pulp_apiObject Also known as: pulp_node



180
181
182
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 180

def pulp_api
  @pulp_api ||= Katello::Pulp::Server.config(pulp_url, User.remote_user)
end

#pulp_content_urlObject



458
459
460
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 458

def pulp_content_url
  URI(setting(SmartProxy::PULP3_FEATURE, 'content_app_url'))
end

#pulp_disk_usageObject



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 210

def pulp_disk_usage
  if has_feature?(PULP_FEATURE) || has_feature?(PULP_NODE_FEATURE)
    status = self.statuses[:pulp] || self.statuses[:pulpnode]
    status&.storage&.map do |label, results|
      {
        description: results['path'],
        total: results['1k-blocks'] * 1024,
        used: results['used'] * 1024,
        free: results['available'] * 1024,
        percentage: (results['used'] / results['1k-blocks'].to_f * 100).to_i,
        label: label
      }.with_indifferent_access
    end
  elsif pulp3_enabled?
    storage = ping_pulp3['storage']
    [
      {
        description: 'Pulp Storage (/var/lib/pulp by default)',
        total: storage['total'],
        used: storage['used'],
        free: storage['free'],
        percentage: (storage['used'] / storage['total'].to_f * 100).to_i,
        label: 'pulp_dir'
      }.with_indifferent_access
    ]
  end
end

#pulp_mirror?Boolean



300
301
302
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 300

def pulp_mirror?
  self.has_feature?(PULP_NODE_FEATURE) || self.setting(SmartProxy::PULP3_FEATURE, 'mirror')
end

#pulp_primary?Boolean Also known as: default_capsule?



304
305
306
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 304

def pulp_primary?
  self.has_feature?(PULP_FEATURE) || self.setting(SmartProxy::PULP3_FEATURE, 'mirror') == false
end

#pulp_urlObject



175
176
177
178
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 175

def pulp_url
  uri = URI.parse(url)
  "#{uri.scheme}://#{uri.host}/pulp/api/v2/"
end

#remove_lifecycle_environment(environment) ⇒ Object



363
364
365
366
367
368
369
370
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 363

def remove_lifecycle_environment(environment)
  self.lifecycle_environments.find(environment.id)
  unless self.lifecycle_environments.destroy(environment)
    fail _("Could not remove the lifecycle environment from the smart proxy")
  end
rescue ActiveRecord::RecordNotFound
  raise _("Lifecycle environment was not attached to the smart proxy; therefore, no changes were made.")
end

#repos_in_env_cv(environment = nil, content_view = nil) ⇒ Object



426
427
428
429
430
431
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 426

def repos_in_env_cv(environment = nil, content_view = nil)
  repos = Katello::Repository
  repos = repos.in_environment(environment) if environment
  repos = repos.in_content_views([content_view]) if content_view
  repos.respond_to?(:to_a) ? repos : repos.none
end

#repos_in_sync_historyObject



433
434
435
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 433

def repos_in_sync_history
  smart_proxy_sync_histories.map { |sync_history| sync_history.repository }
end

#repos_pending_sync(environment = nil, content_view = nil) ⇒ Object



442
443
444
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 442

def repos_pending_sync(environment = nil, content_view = nil)
  repos_in_env_cv(environment, content_view) - repos_in_sync_history
end

#rhsm_urlObject



446
447
448
449
450
451
452
453
454
455
456
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 446

def rhsm_url
  # Since Foreman 3.1 this setting is set
  if (rhsm_url = setting(SmartProxy::PULP3_FEATURE, 'rhsm_url'))
    URI(rhsm_url)
    # Compatibility fall back
  elsif pulp_primary?
    URI("https://#{URI.parse(url).host}/rhsm")
  elsif pulp_mirror?
    URI("https://#{URI.parse(url).host}:8443/rhsm")
  end
end

#set_default_download_policyObject



351
352
353
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 351

def set_default_download_policy
  self.download_policy ||= ::Setting[:default_proxy_download_policy] || ::Katello::RootRepository::DOWNLOAD_ON_DEMAND
end

#supported_pulp_typesObject



308
309
310
311
312
313
314
315
316
317
318
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 308

def supported_pulp_types
  supported_types = []

  ::Katello::RepositoryTypeManager.enabled_repository_types.keys.each do |type|
    if pulp3_repository_type_support?(type)
      supported_types << type
    end
  end

  supported_types
end

#sync_container_gatewayObject



124
125
126
127
128
129
130
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 124

def sync_container_gateway
  if has_feature?(::SmartProxy::CONTAINER_GATEWAY_FEATURE)
    update_container_repo_list
    users = container_gateway_users
    update_user_container_repo_mapping(users) if users.any?
  end
end

#sync_tasksObject



378
379
380
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 378

def sync_tasks
  ForemanTasks::Task.for_resource(self).where(:label => 'Actions::Katello::CapsuleContent::Sync')
end

#unauthenticated_container_repositoriesObject



166
167
168
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 166

def unauthenticated_container_repositories
  ::Katello::Repository.joins(:environment).where("#{::Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id).pluck(:id)
end

#update_container_repo_listObject



132
133
134
135
136
137
138
139
140
141
142
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 132

def update_container_repo_list
  # [{ repository: "repoA", auth_required: false }]
  repo_list = []
  ::Katello::SmartProxyHelper.new(self).combined_repos_available_to_capsule.each do |repo|
    if repo.docker? && !repo.container_repository_name.nil?
      repo_list << { repository: repo.container_repository_name,
                     auth_required: !unauthenticated_container_repositories.include?(repo.id) }
    end
  end
  ::ProxyAPI::ContainerGateway.new(url: self.url).repository_list({ repositories: repo_list })
end

#update_user_container_repo_mapping(users) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 144

def update_user_container_repo_mapping(users)
  # Example user-repo mapping:
  # { users:
  #   [
  #     'user a' => [{ repository: 'repo 1', auth_required: true }]
  #   ]
  # }

  user_repo_map = { users: [] }
  users.each do |user|
    inner_repo_list = []
    repositories = ::Katello::Repository.readable_docker_catalog_as(user)
    repositories.each do |repo|
      next if repo.container_repository_name.nil?
      inner_repo_list << { repository: repo.container_repository_name,
                           auth_required: !unauthenticated_container_repositories.include?(repo.id) }
    end
    user_repo_map[:users] << { user. => inner_repo_list }
  end
  ProxyAPI::ContainerGateway.new(url: self.url).user_repository_mapping(user_repo_map)
end

#verify_ueber_certsObject



420
421
422
423
424
# File 'app/models/katello/concerns/smart_proxy_extensions.rb', line 420

def verify_ueber_certs
  self.organizations.each do |org|
    Cert::Certs.verify_ueber_cert(org)
  end
end