topological_inventory-providers-common 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|