topological_inventory-providers-common 1.0.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -2
  3. data/lib/topological_inventory/providers/common.rb +1 -2
  4. data/lib/topological_inventory/providers/common/collector.rb +12 -4
  5. data/lib/topological_inventory/providers/common/collectors_pool.rb +2 -1
  6. data/lib/topological_inventory/providers/common/logging.rb +10 -4
  7. data/lib/topological_inventory/providers/common/mixins/sources_api.rb +58 -0
  8. data/lib/topological_inventory/providers/common/mixins/topology_api.rb +26 -0
  9. data/lib/topological_inventory/providers/common/mixins/x_rh_headers.rb +24 -0
  10. data/lib/topological_inventory/providers/common/operations/async_worker.rb +56 -0
  11. data/lib/topological_inventory/providers/common/operations/health_check.rb +15 -0
  12. data/lib/topological_inventory/providers/common/operations/source.rb +119 -144
  13. data/lib/topological_inventory/providers/common/sources_api_client.rb +92 -0
  14. data/lib/topological_inventory/providers/common/topology_api_client.rb +43 -0
  15. data/lib/topological_inventory/providers/common/version.rb +1 -1
  16. data/spec/support/shared/availability_check.rb +1 -1
  17. data/spec/topological_inventory/providers/common/operations/async_worker_spec.rb +36 -0
  18. data/topological_inventory-providers-common.gemspec +1 -1
  19. metadata +16 -7
  20. data/lib/topological_inventory/providers/common/operations/endpoint_client.rb +0 -65
  21. data/lib/topological_inventory/providers/common/operations/processor.rb +0 -135
  22. data/lib/topological_inventory/providers/common/operations/sources_api_client.rb +0 -94
  23. data/lib/topological_inventory/providers/common/operations/topology_api_client.rb +0 -28
  24. data/spec/topological_inventory/providers/common/operations/processor_spec.rb +0 -102
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22571a5f48d3d126fc3fddd2992643b2dddccc6c2bb20b5eb8263901bf6ca148
4
- data.tar.gz: 437ce9d295f10ab3e10b2b32ea64c89efecd66ff2538c6152f2d67d38f4a9f39
3
+ metadata.gz: 134e945b201072b8bdd7fc6af73b04a6f60698da831ef3989ab973453a1a5159
4
+ data.tar.gz: 20e4f260c411551572b557f4e4454fdc03c9e3b2ac9c8f5997e6600780298c1a
5
5
  SHA512:
6
- metadata.gz: 4abc37ec7c40eef6bdd0e4555404607228edf396b3c9482b7f735419f1359e68bd13139515d9dc2f0a359e28f23e51f38e39877405c5f3e66f7e414f559fce17
7
- data.tar.gz: e2652340645a001205c36f4cfad7fe75f0a0dd18301f27cce72fcf856fb48c4be6b2863c00aa7ed7ae40141f1153096ed1bebae6a478e8854f13a52e8524788f
6
+ metadata.gz: 0a847566f6fb20e9518faef660c626788e6afd20d26cec28a5899e645c68cedd7c017974d0cb1c3c2524253007386b9728a1bb67a0f0a9101fe62bd388f03ccb
7
+ data.tar.gz: 6e786659b1bf913fe1e22d9c0618986d03dc4bc169d782e446ecd089b97a136b639f83be85c562006dccde83a8d025b102863b565aa571746767fa292e4dae89
@@ -4,8 +4,23 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [1.0.8] - 2020-08-10
7
+ ## [2.0.0]
8
+ Operations/API clients refactoring
9
+
10
+ ## [1.0.12] - 2020-10-01
11
+ Add Operations Async Worker class #55
12
+
13
+ ## [1.0.11] - 2020-09-04
14
+ Make Collector Poll Time a parameter so we can tweak the collection interval #51
15
+
16
+ ## [1.0.10] - 2020-08-26
17
+ Add HealthCheck class for operations workers #48
18
+ Set the LOG_LEVEL if present #50
19
+
20
+ ## [1.0.9] - 2020-08-17
8
21
  Added refresh-type to save and sweep inventory #45
22
+
23
+ ## [1.0.8] - 2020-08-12
9
24
  Add => to error messages that rubocop missed #44
10
25
 
11
26
  ## [1.0.7] - 2020-07-27
@@ -47,7 +62,12 @@ manageiq-loggers to >= 0.4.2 #20
47
62
  ## [1.0.0] - 2020-03-19
48
63
  ### Initial release to rubygems.org
49
64
 
50
- [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.8...HEAD
65
+ [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.0.0...HEAD
66
+ [2.0.0]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.12...v2.0.0
67
+ [1.0.12]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.11...v1.0.12
68
+ [1.0.11]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.10...v1.0.11
69
+ [1.0.10]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.9...v1.0.10
70
+ [1.0.9]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.8...v1.0.9
51
71
  [1.0.8]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.7...v1.0.8
52
72
  [1.0.7]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.6...v1.0.7
53
73
  [1.0.6]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.5...v1.0.6
@@ -1,7 +1,6 @@
1
1
  require "topological_inventory/providers/common/version"
2
2
  require "topological_inventory/providers/common/logging"
3
- require "topological_inventory/providers/common/operations/processor"
4
- require "topological_inventory/providers/common/operations/endpoint_client"
3
+ require "topological_inventory/providers/common/operations/health_check"
5
4
  require "topological_inventory/providers/common/collectors_pool"
6
5
  require "topological_inventory/providers/common/collector"
7
6
 
@@ -104,7 +104,8 @@ module TopologicalInventory
104
104
  refresh_state_uuid = nil,
105
105
  refresh_state_part_uuid = nil,
106
106
  refresh_state_part_collected_at = nil,
107
- refresh_state_part_sent_at = Time.now.utc)
107
+ refresh_state_part_sent_at = Time.now.utc,
108
+ refresh_type = default_refresh_type)
108
109
  return 0 if collections.empty?
109
110
 
110
111
  SaveInventory::Saver.new(:client => ingress_api_client, :logger => logger).save(
@@ -116,7 +117,8 @@ module TopologicalInventory
116
117
  :refresh_state_uuid => refresh_state_uuid,
117
118
  :refresh_state_part_uuid => refresh_state_part_uuid,
118
119
  :refresh_state_part_collected_at => refresh_state_part_collected_at,
119
- :refresh_state_part_sent_at => refresh_state_part_sent_at
120
+ :refresh_state_part_sent_at => refresh_state_part_sent_at,
121
+ :refresh_type => refresh_type
120
122
  )
121
123
  )
122
124
  rescue => e
@@ -134,7 +136,8 @@ module TopologicalInventory
134
136
  total_parts,
135
137
  sweep_scope,
136
138
  refresh_state_started_at = nil,
137
- refresh_state_sent_at = Time.now.utc)
139
+ refresh_state_sent_at = Time.now.utc,
140
+ refresh_type = default_refresh_type)
138
141
  return if !total_parts || sweep_scope.empty?
139
142
 
140
143
  SaveInventory::Saver.new(:client => ingress_api_client, :logger => logger).save(
@@ -147,7 +150,8 @@ module TopologicalInventory
147
150
  :total_parts => total_parts,
148
151
  :sweep_scope => sweep_scope,
149
152
  :refresh_state_started_at => refresh_state_started_at,
150
- :refresh_state_sent_at => refresh_state_sent_at
153
+ :refresh_state_sent_at => refresh_state_sent_at,
154
+ :refresh_type => refresh_type
151
155
  )
152
156
  )
153
157
  rescue => e
@@ -165,6 +169,10 @@ module TopologicalInventory
165
169
  "Default"
166
170
  end
167
171
 
172
+ def default_refresh_type
173
+ 'full-refresh'
174
+ end
175
+
168
176
  def ingress_api_client
169
177
  TopologicalInventoryIngressApiClient::DefaultApi.new
170
178
  end
@@ -5,8 +5,9 @@ module TopologicalInventory
5
5
  module Common
6
6
  class CollectorsPool
7
7
  SECRET_FILENAME = "credentials".freeze
8
+ COLLECTOR_POLL_TIME = ENV['COLLECTOR_POLL_TIME']&.to_i || 300
8
9
 
9
- def initialize(config_name, metrics, collector_poll_time: 60, thread_pool_size: 2)
10
+ def initialize(config_name, metrics, collector_poll_time: COLLECTOR_POLL_TIME, thread_pool_size: 2)
10
11
  self.config_name = config_name
11
12
  self.collector_status = Concurrent::Map.new
12
13
  self.metrics = metrics
@@ -23,17 +23,23 @@ module TopologicalInventory
23
23
  end
24
24
 
25
25
  def availability_check(message, severity = :info)
26
- log_with_prefix("Source#availability_check", message, severity)
26
+ send("#{severity}_ext", "Source#availability_check", message)
27
27
  end
28
28
 
29
- def log_with_prefix(prefix, message, severity)
30
- send(severity, "#{prefix} - #{message}") if respond_to?(severity)
29
+ %w[debug info warn error fatal].each do |severity|
30
+ define_method("#{severity}_ext".to_sym) do |prefix, message|
31
+ ext_message = [prefix, message].compact.join(' - ')
32
+ send(severity, ext_message)
33
+ end
31
34
  end
32
35
  end
33
36
 
34
37
  class Logger < ManageIQ::Loggers::CloudWatch
35
38
  def self.new(*args)
36
- super.tap { |logger| logger.extend(TopologicalInventory::Providers::Common::LoggingFunctions) }
39
+ super.tap do |logger|
40
+ logger.extend(TopologicalInventory::Providers::Common::LoggingFunctions)
41
+ logger.level = ENV['LOG_LEVEL'] if ENV['LOG_LEVEL']
42
+ end
37
43
  end
38
44
  end
39
45
 
@@ -0,0 +1,58 @@
1
+ require "topological_inventory/providers/common/sources_api_client"
2
+
3
+ module TopologicalInventory
4
+ module Providers
5
+ module Common
6
+ module Mixins
7
+ module SourcesApi
8
+ AUTH_NOT_NECESSARY = "n/a".freeze
9
+
10
+ def sources_api
11
+ @sources_api ||= TopologicalInventory::Providers::Common::SourcesApiClient.new(identity)
12
+ end
13
+
14
+ def endpoint
15
+ @endpoint ||= sources_api.fetch_default_endpoint(source_id)
16
+ rescue => e
17
+ logger.error_ext(operation, "Failed to fetch Endpoint for Source #{source_id}: #{e.message}")
18
+ nil
19
+ end
20
+
21
+ def authentication
22
+ @authentication ||= if endpoint.receptor_node.present?
23
+ AUTH_NOT_NECESSARY
24
+ else
25
+ sources_api.fetch_authentication(source_id, endpoint)
26
+ end
27
+ rescue => e
28
+ logger.error_ext(operation, "Failed to fetch Authentication for Source #{source_id}: #{e.message}")
29
+ nil
30
+ end
31
+
32
+ def application
33
+ @application ||= sources_api.fetch_application(source_id)
34
+ rescue => e
35
+ logger.error_ext(operation, "Failed to fetch Application for Source #{source_id}: #{e.message}")
36
+ nil
37
+ end
38
+
39
+ def on_premise?
40
+ @on_premise ||= endpoint&.receptor_node.to_s.strip.present?
41
+ end
42
+
43
+ def verify_ssl_mode
44
+ endpoint&.verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
45
+ end
46
+
47
+ def full_hostname(endpoint)
48
+ if on_premise?
49
+ "receptor://#{endpoint.receptor_node}"
50
+ else
51
+ endpoint.host.tap { |host| host << ":#{endpoint.port}" if endpoint.port }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,26 @@
1
+ require "topological_inventory/providers/common/topology_api_client"
2
+
3
+ module TopologicalInventory
4
+ module Providers
5
+ module Common
6
+ module Mixins
7
+ module TopologyApi
8
+ # @identity attr_reader is expected
9
+ def topology_api
10
+ @topology_api ||= TopologicalInventory::Providers::Common::TopologyApiClient.new(identity)
11
+ end
12
+
13
+ def update_task(task_id, source_id: nil, state:, status:, target_type: nil, target_source_ref: nil, context: nil)
14
+ topology_api.update_task(task_id,
15
+ :source_id => source_id,
16
+ :state => state,
17
+ :status => status,
18
+ :target_type => target_type,
19
+ :target_source_ref => target_source_ref,
20
+ :context => context)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module TopologicalInventory
2
+ module Providers
3
+ module Common
4
+ module Mixins
5
+ module XRhHeaders
6
+ def account_number_by_identity(identity)
7
+ return @account_number if @account_number
8
+ return if identity.try(:[], 'x-rh-identity').nil?
9
+
10
+ identity_hash = JSON.parse(Base64.decode64(identity['x-rh-identity']))
11
+ @account_number = identity_hash.dig('identity', 'account_number')
12
+ rescue JSON::ParserError => e
13
+ logger.error_ext(operation, "Failed to parse identity header: #{e.message}")
14
+ nil
15
+ end
16
+
17
+ def identity_by_account_number(account_number)
18
+ @identity ||= {"x-rh-identity" => Base64.strict_encode64({"identity" => {"account_number" => account_number, "user" => {"is_org_admin" => true}}}.to_json)}
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,56 @@
1
+ require "topological_inventory/providers/common/logging"
2
+ require "topological_inventory/providers/common/operations/health_check"
3
+
4
+ module TopologicalInventory
5
+ module Providers
6
+ module Common
7
+ module Operations
8
+ class AsyncWorker
9
+ include Logging
10
+
11
+ def initialize(processor, queue = nil)
12
+ @processor = processor
13
+ @queue = queue || Queue.new
14
+ end
15
+
16
+ def start
17
+ return if thread.present?
18
+
19
+ @thread = Thread.new { listen }
20
+ end
21
+
22
+ def stop
23
+ thread&.exit
24
+ end
25
+
26
+ def enqueue(msg)
27
+ queue << msg
28
+ end
29
+
30
+ def listen
31
+ loop do
32
+ # the queue thread waits for a message to come during `Queue#pop`
33
+ msg = queue.pop
34
+ process_message(msg)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :thread, :queue, :processor
41
+
42
+ def process_message(msg)
43
+ processor.process!(msg)
44
+ rescue => err
45
+ model, method = msg.message.to_s.split(".")
46
+ logger.error("#{model}##{method}: async worker failure: #{err.cause}\n#{err}\n#{err.backtrace.join("\n")}")
47
+ ensure
48
+ msg.ack
49
+ TopologicalInventory::Providers::Common::Operations::HealthCheck.touch_file
50
+ logger.debug("Operations::AsyncWorker queue length: #{queue.length}") if queue.length >= 20 && queue.length % 5 == 0
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,15 @@
1
+ module TopologicalInventory
2
+ module Providers
3
+ module Common
4
+ module Operations
5
+ class HealthCheck
6
+ HEARTBEAT_FILE = '/tmp/healthy'.freeze
7
+
8
+ def self.touch_file
9
+ FileUtils.touch(HEARTBEAT_FILE)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,194 +1,169 @@
1
1
  require "topological_inventory/providers/common/logging"
2
2
  require "active_support/core_ext/numeric/time"
3
- require "topological_inventory/providers/common/operations/sources_api_client"
3
+ require "topological_inventory/providers/common/mixins/sources_api"
4
+ require "topological_inventory/providers/common/mixins/x_rh_headers"
4
5
 
5
6
  module TopologicalInventory
6
7
  module Providers
7
- module Common
8
- module Operations
9
- class Source
10
- include Logging
8
+ module Common
9
+ module Operations
10
+ class Source
11
+ include Logging
12
+ include Mixins::SourcesApi
13
+ include Mixins::XRhHeaders
11
14
 
12
- STATUS_AVAILABLE, STATUS_UNAVAILABLE = %w[available unavailable].freeze
15
+ STATUS_AVAILABLE, STATUS_UNAVAILABLE = %w[available unavailable].freeze
13
16
 
14
- ERROR_MESSAGES = {
15
- :authentication_not_found => "Authentication not found in Sources API",
16
- :endpoint_or_application_not_found => "Endpoint or Application not found in Sources API",
17
- }.freeze
17
+ ERROR_MESSAGES = {
18
+ :authentication_not_found => "Authentication not found in Sources API",
19
+ :endpoint_or_application_not_found => "Endpoint or Application not found in Sources API",
20
+ }.freeze
18
21
 
19
- LAST_CHECKED_AT_THRESHOLD = 5.minutes.freeze
20
- AUTH_NOT_NECESSARY = "n/a".freeze
22
+ LAST_CHECKED_AT_THRESHOLD = 5.minutes.freeze
23
+ AUTH_NOT_NECESSARY = "n/a".freeze
21
24
 
22
- attr_accessor :params, :request_context, :source_id, :account_number
25
+ attr_accessor :identity, :operation, :params, :request_context, :source_id, :account_number
23
26
 
24
- def initialize(params = {}, request_context = nil)
25
- self.params = params
26
- self.request_context = request_context
27
- self.source_id = params['source_id']
28
- self.account_number = params['external_tenant']
29
- end
27
+ def initialize(params = {}, request_context = nil)
28
+ self.operation = 'Source'
29
+ self.params = params
30
+ self.request_context = request_context
31
+ self.source_id = params['source_id']
30
32
 
31
- def availability_check
32
- return if params_missing?
33
+ self.account_number = params['external_tenant']
34
+ self.identity = identity_by_account_number(account_number)
35
+ end
33
36
 
34
- return if checked_recently?
37
+ def availability_check
38
+ self.operation += '#availability_check'
35
39
 
36
- status, error_message = connection_status
40
+ return if params_missing?
37
41
 
38
- update_source_and_subresources(status, error_message)
42
+ return if checked_recently?
39
43
 
40
- logger.availability_check("Completed: Source #{source_id} is #{status}")
41
- end
44
+ status, error_message = connection_status
42
45
 
43
- private
44
-
45
- def required_params
46
- %w[source_id]
47
- end
46
+ update_source_and_subresources(status, error_message)
48
47
 
49
- def params_missing?
50
- is_missing = false
51
- required_params.each do |attr|
52
- if (is_missing = params[attr].blank?)
53
- logger.availability_check("Missing #{attr} for the availability_check request [Source ID: #{source_id}]", :error)
54
- break
55
- end
48
+ logger.availability_check("Completed: Source #{source_id} is #{status}")
56
49
  end
57
50
 
58
- is_missing
59
- end
60
-
61
- def checked_recently?
62
- checked_recently = if endpoint.present?
63
- endpoint.last_checked_at.present? && endpoint.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
64
- elsif application.present?
65
- application.last_checked_at.present? && application.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
66
- end
51
+ private
67
52
 
68
- logger.availability_check("Skipping, last check at #{endpoint.last_checked_at || application.last_checked_at} [Source ID: #{source_id}] ") if checked_recently
69
-
70
- checked_recently
71
- end
53
+ def required_params
54
+ %w[source_id]
55
+ end
72
56
 
73
- def connection_status
74
- # we need either an endpoint or application to check the source.
75
- return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:endpoint_or_application_not_found]] unless endpoint || application
57
+ def params_missing?
58
+ is_missing = false
59
+ required_params.each do |attr|
60
+ if (is_missing = params[attr].blank?)
61
+ logger.availability_check("Missing #{attr} for the availability_check request [Source ID: #{source_id}]", :error)
62
+ break
63
+ end
64
+ end
76
65
 
77
- check_time
78
- if endpoint
79
- endpoint_connection_check
80
- elsif application
81
- application_connection_check
66
+ is_missing
82
67
  end
83
- end
84
68
 
85
- def endpoint_connection_check
86
- return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:authentication_not_found]] unless authentication
69
+ def checked_recently?
70
+ checked_recently = if endpoint.present?
71
+ endpoint.last_checked_at.present? && endpoint.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
72
+ elsif application.present?
73
+ application.last_checked_at.present? && application.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
74
+ end
87
75
 
88
- # call down into the operations pod implementation of `Source#connection_check`
89
- connection_check
90
- end
76
+ logger.availability_check("Skipping, last check at #{endpoint.last_checked_at || application.last_checked_at} [Source ID: #{source_id}] ") if checked_recently
91
77
 
92
- def application_connection_check
93
- case application.availability_status
94
- when "available"
95
- [STATUS_AVAILABLE, nil]
96
- when "unavailable"
97
- [STATUS_UNAVAILABLE, "Application id #{application.id} unavailable"]
78
+ checked_recently
98
79
  end
99
- end
100
80
 
101
- # @return [Array<String, String|nil] - STATUS_[UN]AVAILABLE, error message
102
- def connection_check
103
- raise NotImplementedError, "#{__method__} must be implemented in a subclass"
104
- end
105
-
106
- def update_source_and_subresources(status, error_message = nil)
107
- logger.availability_check("Updating source [#{source_id}] status [#{status}] message [#{error_message}]")
81
+ def connection_status
82
+ # we need either an endpoint or application to check the source.
83
+ return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:endpoint_or_application_not_found]] unless endpoint || application
108
84
 
109
- update_source(status)
85
+ check_time
86
+ if endpoint
87
+ endpoint_connection_check
88
+ elsif application
89
+ application_connection_check
90
+ end
91
+ end
110
92
 
111
- update_endpoint(status, error_message) if endpoint
112
- update_application(status) if application
113
- end
93
+ def endpoint_connection_check
94
+ return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:authentication_not_found]] unless authentication
114
95
 
115
- def update_source(status)
116
- source = ::SourcesApiClient::Source.new
117
- source.availability_status = status
118
- source.last_checked_at = check_time
119
- source.last_available_at = check_time if status == STATUS_AVAILABLE
96
+ # call down into the operations pod implementation of `Source#connection_check`
97
+ connection_check
98
+ end
120
99
 
121
- api_client.update_source(source_id, source)
122
- rescue ::SourcesApiClient::ApiError => e
123
- logger.availability_check("Failed to update Source id:#{source_id} - #{e.message}", :error)
124
- end
100
+ def application_connection_check
101
+ case application.availability_status
102
+ when "available"
103
+ [STATUS_AVAILABLE, nil]
104
+ when "unavailable"
105
+ [STATUS_UNAVAILABLE, "Application id #{application.id} unavailable"]
106
+ end
107
+ end
125
108
 
126
- def update_endpoint(status, error_message)
127
- if endpoint.nil?
128
- logger.availability_check("Failed to update Endpoint for Source id:#{source_id}. Endpoint not found", :error)
129
- return
109
+ # @return [Array<String, String|nil] - STATUS_[UN]AVAILABLE, error message
110
+ def connection_check
111
+ raise NotImplementedError, "#{__method__} must be implemented in a subclass"
130
112
  end
131
113
 
132
- endpoint_update = ::SourcesApiClient::Endpoint.new
114
+ def update_source_and_subresources(status, error_message = nil)
115
+ logger.availability_check("Updating source [#{source_id}] status [#{status}] message [#{error_message}]")
133
116
 
134
- endpoint_update.availability_status = status
135
- endpoint_update.availability_status_error = error_message.to_s
136
- endpoint_update.last_checked_at = check_time
137
- endpoint_update.last_available_at = check_time if status == STATUS_AVAILABLE
117
+ update_source(status)
138
118
 
139
- api_client.update_endpoint(endpoint.id, endpoint_update)
140
- rescue ::SourcesApiClient::ApiError => e
141
- logger.availability_check("Failed to update Endpoint(ID: #{endpoint.id}) - #{e.message}", :error)
142
- end
119
+ update_endpoint(status, error_message) if endpoint
120
+ update_application(status) if application
121
+ end
143
122
 
144
- def update_application(status)
145
- application_update = ::SourcesApiClient::Application.new
146
- application_update.last_checked_at = check_time
147
- application_update.last_available_at = check_time if status == STATUS_AVAILABLE
123
+ def update_source(status)
124
+ source = ::SourcesApiClient::Source.new
125
+ source.availability_status = status
126
+ source.last_checked_at = check_time
127
+ source.last_available_at = check_time if status == STATUS_AVAILABLE
148
128
 
149
- api_client.update_application(application.id, application_update)
150
- rescue ::SourcesApiClient::ApiError => e
151
- logger.availability_check("Failed to update Application id: #{application.id} - #{e.message}", :error)
152
- end
129
+ sources_api.update_source(source_id, source)
130
+ rescue ::SourcesApiClient::ApiError => e
131
+ logger.availability_check("Failed to update Source id:#{source_id} - #{e.message}", :error)
132
+ end
153
133
 
154
- def endpoint
155
- @endpoint ||= api_client.fetch_default_endpoint(source_id)
156
- rescue => e
157
- logger.availability_check("Failed to fetch Endpoint for Source #{source_id}: #{e.message}", :error)
158
- nil
159
- end
134
+ def update_endpoint(status, error_message)
135
+ if endpoint.nil?
136
+ logger.availability_check("Failed to update Endpoint for Source id:#{source_id}. Endpoint not found", :error)
137
+ return
138
+ end
160
139
 
161
- def authentication
162
- @authentication ||= if endpoint.receptor_node.present?
163
- AUTH_NOT_NECESSARY
164
- else
165
- api_client.fetch_authentication(source_id, endpoint)
166
- end
167
- rescue => e
168
- logger.availability_check("Failed to fetch Authentication for Source #{source_id}: #{e.message}", :error)
169
- nil
170
- end
140
+ endpoint_update = ::SourcesApiClient::Endpoint.new
171
141
 
172
- def application
173
- @application ||= api_client.fetch_application(source_id)
174
- rescue => e
175
- logger.availability_check("Failed to fetch Application for Source #{source_id}: #{e.message}", :error)
176
- nil
177
- end
142
+ endpoint_update.availability_status = status
143
+ endpoint_update.availability_status_error = error_message.to_s
144
+ endpoint_update.last_checked_at = check_time
145
+ endpoint_update.last_available_at = check_time if status == STATUS_AVAILABLE
178
146
 
179
- def check_time
180
- @check_time ||= Time.now.utc
181
- end
147
+ sources_api.update_endpoint(endpoint.id, endpoint_update)
148
+ rescue ::SourcesApiClient::ApiError => e
149
+ logger.availability_check("Failed to update Endpoint(ID: #{endpoint.id}) - #{e.message}", :error)
150
+ end
182
151
 
183
- def identity
184
- @identity ||= {"x-rh-identity" => Base64.strict_encode64({"identity" => {"account_number" => account_number, "user" => {"is_org_admin" => true}}}.to_json)}
185
- end
152
+ def update_application(status)
153
+ application_update = ::SourcesApiClient::Application.new
154
+ application_update.last_checked_at = check_time
155
+ application_update.last_available_at = check_time if status == STATUS_AVAILABLE
186
156
 
187
- def api_client
188
- @api_client ||= TopologicalInventory::Providers::Common::Operations::SourcesApiClient.new(identity)
157
+ sources_api.update_application(application.id, application_update)
158
+ rescue ::SourcesApiClient::ApiError => e
159
+ logger.availability_check("Failed to update Application id: #{application.id} - #{e.message}", :error)
160
+ end
161
+
162
+ def check_time
163
+ @check_time ||= Time.now.utc
164
+ end
189
165
  end
190
166
  end
191
167
  end
192
168
  end
193
- end
194
169
  end