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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcac7f624e6e6d2ba88bed97e3d089cfd4258e38b968cbed141528888ede0ca0
4
- data.tar.gz: 7fe176f46948a2359192f503091bce1fadfe3abbb089e4c8efc5606ea07e6ed0
3
+ metadata.gz: 00d8f69979f477e6b74d6c7b2785647cc043b3909a45ff424562504146955e2b
4
+ data.tar.gz: 1b009a746f92137d0502c71bf67346ba86de56aba196eb05e52a6280b86861ec
5
5
  SHA512:
6
- metadata.gz: 2609f90ca604593f8d1bed9c0567feae6151bb6a0805a6299a9077e8b812a58d49573e32eb1cc7a0ff9cf70369c8d7936f88887c4c0b6a7af7f9e50d1013275c
7
- data.tar.gz: 36a45b32003a82705b03d15bc15fbdae18038fc04c2238db55b0077c50868b39ea199de86185a6b00c2d9afc6ce76d9308db8c0ef5ddbc844ef57340f71d6eb7
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
@@ -11,3 +11,6 @@
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+
15
+ # generated rubocop file
16
+ .rubocop-https*
@@ -0,0 +1,3 @@
1
+ inherit_from:
2
+ - https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml
3
+ - .rubocop_local.yml
@@ -0,0 +1,4 @@
1
+ inherit_from:
2
+ - .rubocop_base.yml
3
+ - .rubocop_cc_base.yml
4
+ - .rubocop_local.yml
@@ -0,0 +1,2 @@
1
+ #AllCops:
2
+ # Exclude:
@@ -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"
@@ -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.3] - 2020-06-?
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.3...HEAD
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
- endpoint = endpoints.find(&:default)
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 = endpoint_authentications.first.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 200 bytes, just for sure.
12
- KAFKA_RESERVED_HEADER_SIZE = 200
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: 1_000_000)
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 - KAFKA_RESERVED_HEADER_SIZE
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
@@ -1,7 +1,7 @@
1
1
  module TopologicalInventory
2
2
  module Providers
3
3
  module Common
4
- VERSION = "1.0.3"
4
+ VERSION = "1.0.4"
5
5
  end
6
6
  end
7
7
  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.3
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-04 00:00:00.000000000 Z
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