Module: Katello::Glue::Provider::InstanceMethods

Defined in:
app/models/katello/glue/provider.rb

Instance Method Summary collapse

Instance Method Details

#del_owner_importObject



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'app/models/katello/glue/provider.rb', line 169

def del_owner_import
  # This method will delete a manifest that has been imported.  Since it is not possible
  # to delete the changes associated with a specific manifest, we only support deleting
  # the import, if there has only been 1 manifest import completed.  It should be noted
  # that this will destroy all subscriptions associated with the import.
  imports = self.owner_imports
  if imports.length == 1
    Rails.logger.debug "Deleting import for provider: #{name}"
    Resources::Candlepin::Owner.destroy_imports self.organization.label
  else
    Rails.logger.debug "Unable to delete import for provider: #{name}. Reason: a successful import was previously completed."
  end
end

#del_productsObject



110
111
112
113
114
115
116
117
# File 'app/models/katello/glue/provider.rb', line 110

def del_products
  Rails.logger.debug "Deleting all products for provider: #{name}"
  self.products.uniq.each(&:destroy)
  true
rescue => e
  Rails.logger.error "Failed to delete all products for provider #{name}: #{e}, #{e.backtrace.join("\n")}"
  raise e
end

#delete_manifestObject



18
19
20
# File 'app/models/katello/glue/provider.rb', line 18

def delete_manifest
  queue_delete_manifest
end

#destroy_products_orchestrationObject



280
281
282
# File 'app/models/katello/glue/provider.rb', line 280

def destroy_products_orchestration
  pre_queue.create(:name => "delete products for provider: #{self.name}", :priority => 1, :action => [self, :del_products])
end

#exec_delete_manifestObject



300
301
302
303
# File 'app/models/katello/glue/provider.rb', line 300

def exec_delete_manifest
  Resources::Candlepin::Owner.destroy_imports self.organization.label, true
  index_subscriptions
end

#import_error_message(display_message) ⇒ Object



284
285
286
287
288
289
290
# File 'app/models/katello/glue/provider.rb', line 284

def import_error_message(display_message)
  error_texts = [
    _("Subscription manifest upload for provider '%s' failed.") % self.name,
    (_("Reason: %s") % display_message unless display_message.blank?)
  ].compact
  error_texts.join('<br />')
end

#import_loggerObject



187
188
189
# File 'app/models/katello/glue/provider.rb', line 187

def import_logger
  ::Foreman::Logging.logger('katello/manifest_import_logger')
end

#import_manifest(zip_file_path, options = {}) ⇒ Object



11
12
13
14
15
16
# File 'app/models/katello/glue/provider.rb', line 11

def import_manifest(zip_file_path, options = {})
  options = {:zip_file_path => zip_file_path}.merge(options)
  options.assert_valid_keys(:force, :zip_file_path)

  queue_import_manifest options
end

#import_products_from_cpObject

TODO: break up method



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'app/models/katello/glue/provider.rb', line 237

def import_products_from_cp # rubocop:disable MethodLength
  product_in_katello_ids = self.organization.providers.redhat.first.products.pluck("cp_id")
  products_in_candlepin_ids = []

  marketing_to_engineering_product_ids_mapping.each do |marketing_product_id, engineering_product_ids|
    engineering_product_ids = engineering_product_ids.uniq
    products_in_candlepin_ids << marketing_product_id
    products_in_candlepin_ids.concat(engineering_product_ids)
    added_eng_products = (engineering_product_ids - product_in_katello_ids).map do |id|
      Resources::Candlepin::Product.get(id)[0]
    end
    adjusted_eng_products = []
    added_eng_products.each do |product_attrs|
      begin
        Glue::Candlepin::Product.import_from_cp(product_attrs) do |p|
          p.provider = self
          p.organization_id = self.organization.id
        end
        adjusted_eng_products << product_attrs
        import_logger.info "import of product '#{product_attrs["name"]}' from Candlepin OK"
      rescue Errors::SecurityViolation => e
        # Do not add non-accessible products
        logger.info "import of product '#{product_attrs["name"]}' from Candlepin failed"
        import_logger.info e
      end
    end

    product_in_katello_ids.concat(adjusted_eng_products.map { |p| p["id"] })

    marketing_product = Katello::Product.find_by_cp_id(marketing_product_id)
    marketing_product.destroy if marketing_product && marketing_product.redhat?
  end

  product_to_remove_ids = (product_in_katello_ids - products_in_candlepin_ids).uniq
  product_to_remove_ids.each do |cp_id|
    product = Product.find_by_cp_id(cp_id, self.organization)
    Rails.logger.warn "Orphaned Product id #{product.id} found while refreshing/importing manifest."
  end

  self.index_subscriptions
  true
end

#index_subscriptionsObject



305
306
307
308
# File 'app/models/katello/glue/provider.rb', line 305

def index_subscriptions
  Katello::Subscription.import_all
  Katello::Pool.import_all
end

#last_syncObject



94
95
96
97
98
99
100
101
102
103
# File 'app/models/katello/glue/provider.rb', line 94

def last_sync
  sync_times = []
  self.products.each do |prod|
    break unless prod.respond_to?(:last_sync)
    sync = prod.last_sync
    sync_times << sync unless sync.nil?
  end
  sync_times.sort!
  sync_times.last
end

#latest_sync_statusesObject

get last sync status of all repositories in this provider



42
43
44
45
46
47
# File 'app/models/katello/glue/provider.rb', line 42

def latest_sync_statuses
  statuses = self.products.collect do |p|
    p.latest_sync_statuses
  end
  statuses.flatten
end

#owner_import(zip_file_path, options) ⇒ Object



119
120
121
# File 'app/models/katello/glue/provider.rb', line 119

def owner_import(zip_file_path, options)
  Resources::Candlepin::Owner.import self.organization.label, zip_file_path, options
end

#owner_importsObject



183
184
185
# File 'app/models/katello/glue/provider.rb', line 183

def owner_imports
  Resources::Candlepin::Owner.imports self.organization.label
end

#owner_upstream_export(upstream, zip_file_path, _options) ⇒ Object



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

def owner_upstream_export(upstream, zip_file_path, _options)
  if !upstream['idCert'] || !upstream['idCert']['cert'] || !upstream['idCert']['key']
    Rails.logger.error "Upstream identity certificate not available"
    fail _("Upstream identity certificate not available")
  end

  # Default to Red Hat
  url = upstream['apiUrl'] || 'https://subscription.rhn.redhat.com/subscription/consumers/'

  # TODO: wait until ca_path is supported
  #       https://github.com/L2G/rest-client-fork/pull/8
  #ca_file = '/etc/candlepin/certs/upstream/subscription.rhn.stage.redhat.com.crt'
  ca_file = nil

  data = Resources::Candlepin::UpstreamConsumer.export("#{url}#{upstream['uuid']}/export", upstream['idCert']['cert'],
                                                       upstream['idCert']['key'], ca_file)

  File.open(zip_file_path, 'w') do |f|
    f.binmode
    f.write data
  end

  return true
end

#owner_upstream_update(upstream, _options) ⇒ Object



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

def owner_upstream_update(upstream, _options)
  if !upstream['idCert'] || !upstream['idCert']['cert'] || !upstream['idCert']['key']
    Rails.logger.error "Upstream identity certificate not available"
    fail _("Upstream identity certificate not available")
  end

  # Default to Red Hat
  url = upstream['apiUrl'] || 'https://subscription.rhn.redhat.com/subscription/consumers/'

  # TODO: wait until ca_path is supported
  #       https://github.com/L2G/rest-client-fork/pull/8
  #ca_file = '/etc/candlepin/certs/upstream/subscription.rhn.stage.redhat.com.crt'
  ca_file = nil

  capabilities = Resources::Candlepin::CandlepinPing.ping['managerCapabilities'].inject([]) do |result, element|
    result << {'name' => element}
  end
  Resources::Candlepin::UpstreamConsumer.update("#{url}#{upstream['uuid']}", upstream['idCert']['cert'],
                                                upstream['idCert']['key'], ca_file, :capabilities => capabilities)
end

#queue_delete_manifestObject



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'app/models/katello/glue/provider.rb', line 314

def queue_delete_manifest
  import_logger.debug "Deleting manifest for provider #{self.name}"

  begin
    pre_queue.create(:name     => "delete manifest for owner: #{self.organization.name}",
                     :priority => 3, :action => [self, :exec_delete_manifest],
                     :action_rollback => [self, :rollback_delete_manifest])
    if SETTINGS[:katello][:use_pulp]
      pre_queue.create(:name => "refresh product repos for deletion",
                       :priority => 6, :action => [self, :refresh_existing_products])
    end
    self.save!
  rescue => error
    display_manifest_message('delete', error)
    raise error
  end
end

#queue_import_manifest(options) ⇒ Object

TODO: break up method



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'app/models/katello/glue/provider.rb', line 192

def queue_import_manifest(options)
  options = options.with_indifferent_access
  fail "zip_file_path or upstream must be specified" if options[:zip_file_path].nil? && options[:upstream].nil?

  #if a manifest has already been imported, we need to update the products
  manifest_update = self.products.any?
  #are we refreshing from upstream?
  manifest_refresh = options['zip_file_path'].nil?

  import_logger.debug "Importing manifest for provider #{self.name}"

  begin
    if manifest_refresh
      zip_file_path = "/tmp/#{rand}.zip"
      upstream = options[:upstream]
      pre_queue.create(:name => "export upstream manifest for owner: #{self.organization.name}",
                       :priority => 2, :action => [self, :owner_upstream_update, upstream, options],
                       :action_rollback => nil)
      pre_queue.create(:name => "export upstream manifest for owner: #{self.organization.name}",
                       :priority => 3, :action => [self, :owner_upstream_export, upstream, zip_file_path, options],
                       :action_rollback => nil)
    else
      zip_file_path = options[:zip_file_path]
    end

    pre_queue.create(:name     => "import manifest #{zip_file_path} for owner: #{self.organization.name}",
                     :priority => 4, :action => [self, :owner_import, zip_file_path, options],
                     :action_rollback => [self, :del_owner_import])
    pre_queue.create(:name     => "import of products in manifest #{zip_file_path}",
                     :priority => 5, :action => [self, :import_products_from_cp])
    pre_queue.create(:name     => "refresh product repos",
                     :priority => 6, :action => [self, :refresh_existing_products]) if manifest_update && SETTINGS[:katello][:use_pulp]

    self.save!
  rescue => error
    display_manifest_message(manifest_refresh ? 'refresh' : 'import', error)
    raise error
  end
end

#refresh_error_message(display_message) ⇒ Object



292
293
294
295
296
297
298
# File 'app/models/katello/glue/provider.rb', line 292

def refresh_error_message(display_message)
  error_texts = [
    _("Subscription manifest refresh for provider '%s' failed.") % self.name,
    (_("Reason: %s") % display_message unless display_message.blank?)
  ].compact
  error_texts.join('<br />')
end

#refresh_existing_productsObject



232
233
234
# File 'app/models/katello/glue/provider.rb', line 232

def refresh_existing_products
  self.products.each { |p| p.update_repositories }
end

#refresh_manifest(upstream, options = {}) ⇒ Object



22
23
24
25
26
27
# File 'app/models/katello/glue/provider.rb', line 22

def refresh_manifest(upstream, options = {})
  options = { :upstream => upstream }.merge(options)
  options.assert_valid_keys(:upstream)

  queue_import_manifest(options)
end

#rollback_delete_manifestObject



310
311
312
# File 'app/models/katello/glue/provider.rb', line 310

def rollback_delete_manifest
  # Nothing to be done until implemented in katello where possible pulp recovery actions should be done(?)
end

#rules_sourceObject



332
333
334
# File 'app/models/katello/glue/provider.rb', line 332

def rules_source
  redhat_provider? ? candlepin_ping['rulesSource'] : ''
end

#rules_versionObject



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

def rules_version
  redhat_provider? ? candlepin_ping['rulesVersion'] : ''
end

#syncObject



29
30
31
32
33
34
35
# File 'app/models/katello/glue/provider.rb', line 29

def sync
  Rails.logger.debug "Syncing provider #{name}"
  syncs = self.products.collect do |p|
    p.sync
  end
  syncs.flatten
end

#sync_finishObject



80
81
82
83
84
85
86
87
88
# File 'app/models/katello/glue/provider.rb', line 80

def sync_finish
  finish_times = []
  self.products.each do |r|
    finish = r.sync_finish
    finish_times << finish unless finish.nil?
  end
  finish_times.sort!
  finish_times.last
end

#sync_sizeObject



90
91
92
# File 'app/models/katello/glue/provider.rb', line 90

def sync_size
  self.products.inject(0) { |sum, v| sum + v.sync_status.progress.total_size }
end

#sync_startObject



70
71
72
73
74
75
76
77
78
# File 'app/models/katello/glue/provider.rb', line 70

def sync_start
  start_times = []
  self.products.each do |prod|
    start = prod.sync_start
    start_times << start unless start.nil?
  end
  start_times.sort!
  start_times.last
end

#sync_stateObject



66
67
68
# File 'app/models/katello/glue/provider.rb', line 66

def sync_state
  self.sync_status[:state]
end

#sync_statusObject

Get the most relavant status for all the repos in this Provider



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'app/models/katello/glue/provider.rb', line 50

def sync_status
  statuses = self.products.reject { |r| r.empty? }.map { |r| r.sync_status }
  return PulpSyncStatus.new(:state => PulpSyncStatus::Status::NOT_SYNCED) if statuses.empty?

  [PulpSyncStatus::Status::RUNNING,
   PulpSyncStatus::Status::NOT_SYNCED,
   PulpSyncStatus::Status::CANCELED,
   PulpSyncStatus::Status::ERROR].each do |interesting_status|
    relevant_status =  statuses.find { |s| s[:state].to_s == interesting_status.to_s }
    return relevant_status if relevant_status
  end

  #else -> all finished
  return statuses[0]
end

#synced?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'app/models/katello/glue/provider.rb', line 37

def synced?
  self.products.any? { |p| p.synced? }
end

#url_to_host_and_path(url = "") ⇒ Object



105
106
107
108
# File 'app/models/katello/glue/provider.rb', line 105

def url_to_host_and_path(url = "")
  parsed = URI.parse(url)
  ["#{parsed.scheme}://#{parsed.host}#{ parsed.port ? ':' + parsed.port.to_s : '' }", parsed.path]
end