topological_inventory-providers-common 1.0.3 → 1.0.4
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.
- checksums.yaml +4 -4
- data/.github/workflows/gem-push.yml +23 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_cc.yml +4 -0
- data/.rubocop_local.yml +2 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +7 -2
- data/lib/topological_inventory/providers/common/logging.rb +8 -0
- data/lib/topological_inventory/providers/common/operations/endpoint_client.rb +3 -0
- data/lib/topological_inventory/providers/common/operations/source.rb +140 -0
- data/lib/topological_inventory/providers/common/operations/sources_api_client.rb +11 -7
- data/lib/topological_inventory/providers/common/save_inventory/saver.rb +13 -4
- data/lib/topological_inventory/providers/common/version.rb +1 -1
- data/topological_inventory-providers-common.gemspec +4 -0
- metadata +63 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00d8f69979f477e6b74d6c7b2785647cc043b3909a45ff424562504146955e2b
|
4
|
+
data.tar.gz: 1b009a746f92137d0502c71bf67346ba86de56aba196eb05e52a6280b86861ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84a4936e15d4fa024d425d430ba2489485259e59be735e86aa3801852b5745825b324a58b2e847781700607d76c1e5e2deb13bb453f019dba2b0e5382f705c8b
|
7
|
+
data.tar.gz: 10e5edc584fbfcfd85ae196aef5f83c1e7e42fb0e4325f29b302feecc8c2937925580e23d903442546e8af826afb91fd8c9ea2164812f4e1baabed2087fb6025
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Release Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
paths:
|
7
|
+
- 'lib/topological_inventory/providers/common/version.rb'
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
name: Build + Publish
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- uses: actions/checkout@v1
|
16
|
+
|
17
|
+
- name: Publish to Rubygems
|
18
|
+
uses: cadwallion/publish-rubygems-action@v1.0
|
19
|
+
env:
|
20
|
+
GITHUB_TOKEN: ${{secrets.GH_API_KEY}}
|
21
|
+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
|
22
|
+
RELEASE_COMMAND: rake release
|
23
|
+
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/.rubocop_cc.yml
ADDED
data/.rubocop_local.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
---
|
2
|
+
dist: xenial
|
2
3
|
sudo: false
|
3
4
|
language: ruby
|
4
5
|
cache: bundler
|
@@ -8,3 +9,10 @@ rvm:
|
|
8
9
|
before_install:
|
9
10
|
- 'echo ''gem: --no-ri --no-rdoc --no-document'' > ~/.gemrc'
|
10
11
|
- gem install bundler
|
12
|
+
before_script:
|
13
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
|
14
|
+
> ./cc-test-reporter
|
15
|
+
- chmod +x ./cc-test-reporter
|
16
|
+
- "./cc-test-reporter before-build"
|
17
|
+
after_script:
|
18
|
+
- "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,11 @@ 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.
|
7
|
+
## [1.0.4] - 2020-06-09
|
8
|
+
Common availability check operation #25
|
9
|
+
Rubocop and codecoverage #29
|
10
|
+
|
11
|
+
## [1.0.3] - 2020-06-04
|
8
12
|
### Changed
|
9
13
|
|
10
14
|
Bump Sources API client to 3.0 #26
|
@@ -25,7 +29,8 @@ manageiq-loggers to >= 0.4.2 #20
|
|
25
29
|
## [1.0.0] - 2020-03-19
|
26
30
|
### Initial release to rubygems.org
|
27
31
|
|
28
|
-
[Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.
|
32
|
+
[Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.4...HEAD
|
33
|
+
[1.0.4]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.3...v1.0.4
|
29
34
|
[1.0.3]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.2...v1.0.3
|
30
35
|
[1.0.2]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.1...v1.0.2
|
31
36
|
[1.0.1]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.0...v1.0.1
|
@@ -21,6 +21,14 @@ module TopologicalInventory
|
|
21
21
|
msg = "[#{status.to_s.upcase}] Sweeping inactive records, :sweep_scope => #{sweep_scope}, :source_uid => #{source}, :refresh_state_uuid => #{refresh_state_uuid}"
|
22
22
|
info(msg)
|
23
23
|
end
|
24
|
+
|
25
|
+
def availability_check(message, severity = :info)
|
26
|
+
log_with_prefix("Source#availability_check", message, severity)
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_with_prefix(prefix, message, severity)
|
30
|
+
send(severity, "#{prefix} - #{message}") if respond_to?(severity)
|
31
|
+
end
|
24
32
|
end
|
25
33
|
|
26
34
|
class Logger < ManageIQ::Loggers::CloudWatch
|
@@ -46,6 +46,9 @@ module TopologicalInventory
|
|
46
46
|
|
47
47
|
def default_endpoint
|
48
48
|
@default_endpoint ||= sources_api.fetch_default_endpoint(source_id)
|
49
|
+
raise "Sources API: Endpoint not found! (source id: #{source_id})" if @default_endpoint.nil?
|
50
|
+
|
51
|
+
@default_endpoint
|
49
52
|
end
|
50
53
|
|
51
54
|
def authentication
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require "topological_inventory/providers/common/logging"
|
2
|
+
require "active_support/core_ext/numeric/time"
|
3
|
+
require "topological_inventory/providers/common/operations/sources_api_client"
|
4
|
+
|
5
|
+
module TopologicalInventory
|
6
|
+
module Providers
|
7
|
+
module Common
|
8
|
+
module Operations
|
9
|
+
class Source
|
10
|
+
include Logging
|
11
|
+
|
12
|
+
STATUS_AVAILABLE, STATUS_UNAVAILABLE = %w[available unavailable].freeze
|
13
|
+
|
14
|
+
ERROR_MESSAGES = {
|
15
|
+
:authentication_not_found => "Authentication not found in Sources API",
|
16
|
+
:endpoint_not_found => "Endpoint not found in Sources API",
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
LAST_CHECKED_AT_THRESHOLD = 5.minutes.freeze
|
20
|
+
|
21
|
+
attr_accessor :params, :request_context, :source_id
|
22
|
+
|
23
|
+
def initialize(params = {}, request_context = nil)
|
24
|
+
self.params = params
|
25
|
+
self.request_context = request_context
|
26
|
+
self.source_id = params['source_id']
|
27
|
+
end
|
28
|
+
|
29
|
+
def availability_check
|
30
|
+
return if params_missing?
|
31
|
+
|
32
|
+
return if checked_recently?
|
33
|
+
|
34
|
+
status, error_message = connection_status
|
35
|
+
|
36
|
+
update_source_and_endpoint(status, error_message)
|
37
|
+
|
38
|
+
logger.availability_check("Completed: Source #{source_id} is #{status}")
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def required_params
|
44
|
+
%w[source_id]
|
45
|
+
end
|
46
|
+
|
47
|
+
def params_missing?
|
48
|
+
is_missing = false
|
49
|
+
required_params.each do |attr|
|
50
|
+
if (is_missing = params[attr].blank?)
|
51
|
+
logger.availability_check("Missing #{attr} for the availability_check request [Source ID: #{source_id}]", :error)
|
52
|
+
break
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
is_missing
|
57
|
+
end
|
58
|
+
|
59
|
+
def checked_recently?
|
60
|
+
return false if endpoint.nil?
|
61
|
+
|
62
|
+
checked_recently = endpoint.last_checked_at.present? && endpoint.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
|
63
|
+
logger.availability_check("Skipping, last check at #{endpoint.last_checked_at} [Source ID: #{source_id}] ") if checked_recently
|
64
|
+
|
65
|
+
checked_recently
|
66
|
+
end
|
67
|
+
|
68
|
+
def connection_status
|
69
|
+
return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:endpoint_not_found]] unless endpoint
|
70
|
+
return [STATUS_UNAVAILABLE, ERROR_MESSAGES[:authentication_not_found]] unless authentication
|
71
|
+
|
72
|
+
check_time
|
73
|
+
connection_check
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Array<String, String|nil] - STATUS_[UN]AVAILABLE, error message
|
77
|
+
def connection_check
|
78
|
+
raise NotImplementedError, "#{__method__} must be implemented in a subclass"
|
79
|
+
end
|
80
|
+
|
81
|
+
def update_source_and_endpoint(status, error_message = nil)
|
82
|
+
logger.availability_check("Updating source [#{source_id}] status [#{status}] message [#{error_message}]")
|
83
|
+
|
84
|
+
update_source(status)
|
85
|
+
update_endpoint(status, error_message)
|
86
|
+
end
|
87
|
+
|
88
|
+
def update_source(status)
|
89
|
+
source = ::SourcesApiClient::Source.new
|
90
|
+
source.availability_status = status
|
91
|
+
source.last_checked_at = check_time
|
92
|
+
source.last_available_at = check_time if status == STATUS_AVAILABLE
|
93
|
+
|
94
|
+
api_client.update_source(source_id, source)
|
95
|
+
rescue ::SourcesApiClient::ApiError => e
|
96
|
+
logger.availability_check("Failed to update Source id:#{source_id} - #{e.message}", :error)
|
97
|
+
end
|
98
|
+
|
99
|
+
def update_endpoint(status, error_message)
|
100
|
+
if endpoint.nil?
|
101
|
+
logger.availability_check("Failed to update Endpoint for Source id:#{source_id}. Endpoint not found", :error)
|
102
|
+
return
|
103
|
+
end
|
104
|
+
|
105
|
+
endpoint_update = ::SourcesApiClient::Endpoint.new
|
106
|
+
|
107
|
+
endpoint_update.availability_status = status
|
108
|
+
endpoint_update.availability_status_error = error_message.to_s
|
109
|
+
endpoint_update.last_checked_at = check_time
|
110
|
+
endpoint_update.last_available_at = check_time if status == STATUS_AVAILABLE
|
111
|
+
|
112
|
+
api_client.update_endpoint(endpoint.id, endpoint_update)
|
113
|
+
rescue ::SourcesApiClient::ApiError => e
|
114
|
+
logger.availability_check("Failed to update Endpoint(ID: #{endpoint.id}) - #{e.message}", :error)
|
115
|
+
end
|
116
|
+
|
117
|
+
def endpoint
|
118
|
+
@endpoint ||= api_client.fetch_default_endpoint(source_id)
|
119
|
+
end
|
120
|
+
|
121
|
+
def authentication
|
122
|
+
@authentication ||= api_client.fetch_authentication(source_id, endpoint)
|
123
|
+
end
|
124
|
+
|
125
|
+
def check_time
|
126
|
+
@check_time ||= Time.now.utc
|
127
|
+
end
|
128
|
+
|
129
|
+
def identity
|
130
|
+
@identity ||= {"x-rh-identity" => Base64.strict_encode64({"identity" => {"account_number" => params["external_tenant"], "user" => {"is_org_admin" => true}}}.to_json)}
|
131
|
+
end
|
132
|
+
|
133
|
+
def api_client
|
134
|
+
@api_client ||= TopologicalInventory::Providers::Common::Operations::SourcesApiClient.new(identity)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -5,6 +5,8 @@ module TopologicalInventory
|
|
5
5
|
module Common
|
6
6
|
module Operations
|
7
7
|
class SourcesApiClient < ::SourcesApiClient::ApiClient
|
8
|
+
delegate :update_source, :update_endpoint, :to => :api
|
9
|
+
|
8
10
|
INTERNAL_API_PATH = '//internal/v1.0'.freeze
|
9
11
|
|
10
12
|
def initialize(identity = nil)
|
@@ -20,21 +22,23 @@ module TopologicalInventory
|
|
20
22
|
|
21
23
|
def fetch_default_endpoint(source_id)
|
22
24
|
endpoints = api.list_source_endpoints(source_id)&.data || []
|
23
|
-
|
24
|
-
|
25
|
-
raise "Sources API: Endpoint not found! (source id: #{source_id})" if endpoint.nil?
|
26
|
-
|
27
|
-
endpoint
|
25
|
+
endpoints.find(&:default)
|
28
26
|
end
|
29
27
|
|
30
|
-
def fetch_authentication(source_id, default_endpoint = nil)
|
28
|
+
def fetch_authentication(source_id, default_endpoint = nil, authtype = nil)
|
31
29
|
endpoint = default_endpoint || fetch_default_endpoint(source_id)
|
32
30
|
return if endpoint.nil?
|
33
31
|
|
34
32
|
endpoint_authentications = api.list_endpoint_authentications(endpoint.id.to_s).data || []
|
35
33
|
return if endpoint_authentications.empty?
|
36
34
|
|
37
|
-
auth_id =
|
35
|
+
auth_id = if authtype.nil?
|
36
|
+
endpoint_authentications.first&.id
|
37
|
+
else
|
38
|
+
endpoint_authentications.detect { |a| a.authtype = authtype }&.id
|
39
|
+
end
|
40
|
+
return if auth_id.nil?
|
41
|
+
|
38
42
|
fetch_authentication_with_password(auth_id)
|
39
43
|
end
|
40
44
|
|
@@ -8,13 +8,14 @@ module TopologicalInventory
|
|
8
8
|
# As defined in:
|
9
9
|
# https://github.com/zendesk/ruby-kafka/blob/02f7e2816e1130c5202764c275e36837f57ca4af/lib/kafka/protocol/message.rb#L11-L17
|
10
10
|
# There is at least 112 bytes that are added as a message header, so we need to keep room for that. Lets make
|
11
|
-
# it
|
12
|
-
|
11
|
+
# it 512 bytes, just for sure.
|
12
|
+
KAFKA_PAYLOAD_MAX_BYTES_DEFAULT = 750_000
|
13
|
+
KAFKA_RESERVED_HEADER_SIZE = 512
|
13
14
|
|
14
|
-
def initialize(client:, logger:, max_bytes:
|
15
|
+
def initialize(client:, logger:, max_bytes: KAFKA_PAYLOAD_MAX_BYTES_DEFAULT)
|
15
16
|
@client = client
|
16
17
|
@logger = logger
|
17
|
-
@max_bytes = max_bytes
|
18
|
+
@max_bytes = payload_max_size(max_bytes)
|
18
19
|
end
|
19
20
|
|
20
21
|
attr_reader :client, :logger, :max_bytes
|
@@ -117,6 +118,14 @@ module TopologicalInventory
|
|
117
118
|
new_inventory[:collections] = []
|
118
119
|
new_inventory
|
119
120
|
end
|
121
|
+
|
122
|
+
def payload_max_size(max_bytes)
|
123
|
+
if ENV['KAFKA_PAYLOAD_MAX_BYTES']
|
124
|
+
max_bytes.clamp(5_000, ENV['KAFKA_PAYLOAD_MAX_BYTES'].to_i) - KAFKA_RESERVED_HEADER_SIZE
|
125
|
+
else
|
126
|
+
max_bytes - KAFKA_RESERVED_HEADER_SIZE
|
127
|
+
end
|
128
|
+
end
|
120
129
|
end
|
121
130
|
end
|
122
131
|
end
|
@@ -34,4 +34,8 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency "bundler", "~> 2.0"
|
35
35
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
36
36
|
spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
+
spec.add_development_dependency 'rubocop', '~>0.69.0'
|
38
|
+
spec.add_development_dependency 'rubocop-performance', '~>1.3'
|
39
|
+
spec.add_development_dependency "simplecov", "~> 0.17.1"
|
40
|
+
spec.add_development_dependency 'webmock'
|
37
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: topological_inventory-providers-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Slemr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06-
|
11
|
+
date: 2020-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -162,6 +162,62 @@ dependencies:
|
|
162
162
|
- - "~>"
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '3.0'
|
165
|
+
- !ruby/object:Gem::Dependency
|
166
|
+
name: rubocop
|
167
|
+
requirement: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - "~>"
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 0.69.0
|
172
|
+
type: :development
|
173
|
+
prerelease: false
|
174
|
+
version_requirements: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - "~>"
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: 0.69.0
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: rubocop-performance
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - "~>"
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '1.3'
|
186
|
+
type: :development
|
187
|
+
prerelease: false
|
188
|
+
version_requirements: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - "~>"
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '1.3'
|
193
|
+
- !ruby/object:Gem::Dependency
|
194
|
+
name: simplecov
|
195
|
+
requirement: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - "~>"
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: 0.17.1
|
200
|
+
type: :development
|
201
|
+
prerelease: false
|
202
|
+
version_requirements: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - "~>"
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: 0.17.1
|
207
|
+
- !ruby/object:Gem::Dependency
|
208
|
+
name: webmock
|
209
|
+
requirement: !ruby/object:Gem::Requirement
|
210
|
+
requirements:
|
211
|
+
- - ">="
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
requirements:
|
218
|
+
- - ">="
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '0'
|
165
221
|
description: Common classes for topological-inventory collectors/operations
|
166
222
|
email:
|
167
223
|
- mslemr@redhat.com
|
@@ -169,8 +225,12 @@ executables: []
|
|
169
225
|
extensions: []
|
170
226
|
extra_rdoc_files: []
|
171
227
|
files:
|
228
|
+
- ".github/workflows/gem-push.yml"
|
172
229
|
- ".gitignore"
|
173
230
|
- ".rspec"
|
231
|
+
- ".rubocop.yml"
|
232
|
+
- ".rubocop_cc.yml"
|
233
|
+
- ".rubocop_local.yml"
|
174
234
|
- ".travis.yml"
|
175
235
|
- CHANGELOG.md
|
176
236
|
- Gemfile
|
@@ -188,6 +248,7 @@ files:
|
|
188
248
|
- lib/topological_inventory/providers/common/logging.rb
|
189
249
|
- lib/topological_inventory/providers/common/operations/endpoint_client.rb
|
190
250
|
- lib/topological_inventory/providers/common/operations/processor.rb
|
251
|
+
- lib/topological_inventory/providers/common/operations/source.rb
|
191
252
|
- lib/topological_inventory/providers/common/operations/sources_api_client.rb
|
192
253
|
- lib/topological_inventory/providers/common/operations/topology_api_client.rb
|
193
254
|
- lib/topological_inventory/providers/common/save_inventory/exception.rb
|