insights-api-common 3.10.0 → 4.1.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.
- checksums.yaml +4 -4
- data/lib/insights/api/common/application_controller_mixins/exception_handling.rb +29 -2
- data/lib/insights/api/common/graphql/templates/query_type.erb +1 -1
- data/lib/insights/api/common/metrics.rb +19 -1
- data/lib/insights/api/common/open_api.rb +1 -0
- data/lib/insights/api/common/open_api/generator.rb +22 -3
- data/lib/insights/api/common/open_api/serializer.rb +23 -10
- data/lib/insights/api/common/open_api/version_from_prefix.rb +14 -0
- data/lib/insights/api/common/rbac/seed.rb +1 -1
- data/lib/insights/api/common/rbac/service.rb +1 -1
- data/lib/insights/api/common/request.rb +11 -0
- data/lib/insights/api/common/version.rb +1 -1
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e43686bd25c46149f1fd5886e5c60452fd04a06c183042ea4f678f227a6b1ca6
|
4
|
+
data.tar.gz: 882ea648b87f2ee1d7c6c8fa171e85f828c1c46ad818799f3e0d638b4e7b9384
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc9dd41c400b94bf67648ac2ddf0f6b5d30ec44ed17cc5f3294155e518908911e261cd5b304518ed9f730840695c06a2b5ecbbc05a6149f38571d95c1d4d8748
|
7
|
+
data.tar.gz: 92e36a165e0b440a279951f6d5a0e8ddd516eb439b9b31768be0ef880350eacf52b8ec2286552f112553eec01cf72e2ba3d2bb635d6791cdab3ea6e134c267d6
|
@@ -10,8 +10,11 @@ module Insights
|
|
10
10
|
logger.error("#{exception.class.name}: #{exception.message}\n#{exception.backtrace.join("\n")}")
|
11
11
|
errors = Insights::API::Common::ErrorDocument.new.tap do |error_document|
|
12
12
|
exception_list_from(exception).each do |exc|
|
13
|
-
|
14
|
-
|
13
|
+
if api_client_exception?(exc)
|
14
|
+
api_client_errors(exc, error_document)
|
15
|
+
else
|
16
|
+
error_document.add(error_code_from_class(exc).to_s, "#{exc.class}: #{exc.message}")
|
17
|
+
end
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
@@ -35,6 +38,30 @@ module Insights
|
|
35
38
|
DEFAULT_ERROR_CODE
|
36
39
|
end
|
37
40
|
end
|
41
|
+
|
42
|
+
def api_client_exception?(exc)
|
43
|
+
exc.respond_to?(:code) && exc.respond_to?(:response_body) && exc.respond_to?(:response_headers) &&
|
44
|
+
!exc.response_body.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def api_client_errors(exc, error_document)
|
48
|
+
body = json_parsed_body(exc)
|
49
|
+
if body.is_a?(Hash) && body.key?('errors') && body['errors'].is_a?(Array)
|
50
|
+
body['errors'].each do |error|
|
51
|
+
next unless error.key?('status') && error.key?('detail')
|
52
|
+
|
53
|
+
error_document.add(error['status'], error['detail'])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
error_document.add(exc.code.to_s, exc.message )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def json_parsed_body(exc)
|
61
|
+
JSON.parse(exc.response_body)
|
62
|
+
rescue StandardError
|
63
|
+
nil
|
64
|
+
end
|
38
65
|
end
|
39
66
|
end
|
40
67
|
end
|
@@ -2,13 +2,14 @@ module Insights
|
|
2
2
|
module API
|
3
3
|
module Common
|
4
4
|
class Metrics
|
5
|
-
def self.activate(config, prefix)
|
5
|
+
def self.activate(config, prefix, args = {})
|
6
6
|
require 'prometheus_exporter'
|
7
7
|
require 'prometheus_exporter/client'
|
8
8
|
|
9
9
|
ensure_exporter_server
|
10
10
|
enable_in_process_metrics
|
11
11
|
enable_web_server_metrics(prefix)
|
12
|
+
setup_custom_metrics(args[:custom_metrics])
|
12
13
|
end
|
13
14
|
|
14
15
|
private_class_method def self.ensure_exporter_server
|
@@ -33,6 +34,23 @@ module Insights
|
|
33
34
|
require "insights/api/common/middleware/web_server_metrics"
|
34
35
|
Rails.application.middleware.unshift(Insights::API::Common::Middleware::WebServerMetrics, :metrics_prefix => prefix)
|
35
36
|
end
|
37
|
+
|
38
|
+
private_class_method def self.setup_custom_metrics(custom_metrics)
|
39
|
+
return if custom_metrics.nil?
|
40
|
+
|
41
|
+
custom_metrics.each do |metric|
|
42
|
+
instance_variable_set("@#{metric[:name]}_#{metric[:type]}", PrometheusExporter::Client.default.register(metric[:type], metric[:name], metric[:description]))
|
43
|
+
|
44
|
+
define_singleton_method(metric[:name]) do
|
45
|
+
case metric[:type]
|
46
|
+
when :counter
|
47
|
+
instance_variable_get("@#{metric[:name]}_#{metric[:type]}")&.observe(1)
|
48
|
+
else
|
49
|
+
"Metric of type #{metric[:type]} unsupported, implement it in Insights::API::Common::Metrics#L45"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
36
54
|
end
|
37
55
|
end
|
38
56
|
end
|
@@ -48,6 +48,7 @@ module Insights
|
|
48
48
|
ENV['APP_NAME'] = app_name
|
49
49
|
ENV['PATH_PREFIX'] = app_prefix
|
50
50
|
Rails.application.reload_routes!
|
51
|
+
@operation_id_hash = {}
|
51
52
|
end
|
52
53
|
|
53
54
|
def server_base_path
|
@@ -117,8 +118,8 @@ module Insights
|
|
117
118
|
"type" => "object",
|
118
119
|
"properties" => {
|
119
120
|
"status" => {
|
120
|
-
"type" => "
|
121
|
-
"example" => 404
|
121
|
+
"type" => "string",
|
122
|
+
"example" => "404"
|
122
123
|
},
|
123
124
|
"detail" => {
|
124
125
|
"type" => "string",
|
@@ -200,7 +201,7 @@ module Insights
|
|
200
201
|
sub_collection = (primary_collection != klass_name)
|
201
202
|
{
|
202
203
|
"summary" => "List #{klass_name.pluralize}#{" for #{primary_collection}" if sub_collection}",
|
203
|
-
"operationId" =>
|
204
|
+
"operationId" => operation_id(klass_name, primary_collection, sub_collection),
|
204
205
|
"description" => "Returns an array of #{klass_name} objects",
|
205
206
|
"parameters" => [
|
206
207
|
{ "$ref" => "##{PARAMETERS_PATH}/QueryLimit" },
|
@@ -562,6 +563,24 @@ module Insights
|
|
562
563
|
def schema_overrides
|
563
564
|
{}
|
564
565
|
end
|
566
|
+
|
567
|
+
def validate_operation_id(name, klass_name)
|
568
|
+
if @operation_id_hash.key?(name)
|
569
|
+
raise ArgumentError, "operation id cannot be duplicates, #{name} in class #{klass_name} has already been used in class #{@operation_id_hash[name]}"
|
570
|
+
end
|
571
|
+
@operation_id_hash[name] = klass_name
|
572
|
+
end
|
573
|
+
|
574
|
+
def operation_id(klass_name, primary_collection, sub_collection)
|
575
|
+
klass = klass_name.constantize
|
576
|
+
name = if klass.respond_to?(:list_operation_id)
|
577
|
+
klass.send(:list_operation_id)
|
578
|
+
else
|
579
|
+
"list#{primary_collection if sub_collection}#{klass_name.pluralize}"
|
580
|
+
end
|
581
|
+
validate_operation_id(name, klass_name)
|
582
|
+
name
|
583
|
+
end
|
565
584
|
end
|
566
585
|
end
|
567
586
|
end
|
@@ -3,27 +3,40 @@ module Insights
|
|
3
3
|
module Common
|
4
4
|
module OpenApi
|
5
5
|
module Serializer
|
6
|
+
include VersionFromPrefix
|
7
|
+
|
6
8
|
def as_json(arg = {})
|
7
|
-
previous = super
|
9
|
+
previous = super(:except => _excluded_attributes(arg))
|
10
|
+
|
8
11
|
encrypted_columns_set = (self.class.try(:encrypted_columns) || []).to_set
|
9
12
|
encryption_filtered = previous.except(*encrypted_columns_set)
|
10
13
|
return encryption_filtered unless arg.key?(:prefixes)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
attrs = encryption_filtered.slice(*schema["properties"].keys)
|
15
|
-
schema["properties"].keys.each do |name|
|
14
|
+
|
15
|
+
attrs = encryption_filtered.slice(*_schema_properties(arg).keys)
|
16
|
+
_schema_properties(arg).keys.each do |name|
|
16
17
|
next if attrs[name].nil?
|
17
18
|
attrs[name] = attrs[name].iso8601 if attrs[name].kind_of?(Time)
|
18
19
|
attrs[name] = attrs[name].to_s if name.ends_with?("_id") || name == "id"
|
19
|
-
attrs[name] = self.public_send(name) if !attrs.key?(name) && !encrypted_columns_set.include?(name)
|
20
20
|
end
|
21
21
|
attrs.compact
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
private
|
25
|
+
|
26
|
+
def _excluded_attributes(arg)
|
27
|
+
return [] unless arg.key?(:prefixes)
|
28
|
+
|
29
|
+
self.attributes.keys - _schema_properties(arg).keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def _schema_properties(arg)
|
33
|
+
@schema_properties ||= _schema(arg)["properties"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def _schema(arg)
|
37
|
+
version = api_version_from_prefix(arg[:prefixes].first)
|
38
|
+
presentation_name = self.class.try(:presentation_name) || self.class.name
|
39
|
+
::Insights::API::Common::OpenApi::Docs.instance[version].definitions[presentation_name]
|
27
40
|
end
|
28
41
|
end
|
29
42
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Insights
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module OpenApi
|
5
|
+
module VersionFromPrefix
|
6
|
+
def api_version_from_prefix(prefix)
|
7
|
+
/\/?\w+\/v(?<major>\d+)[x\.]?(?<minor>\d+)?\// =~ prefix
|
8
|
+
[major, minor].compact.join(".")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -25,6 +25,14 @@ module Insights
|
|
25
25
|
Thread.current[:current_request]
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.current_request_id
|
29
|
+
Thread.current[:request_id]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.current_request_id=(id)
|
33
|
+
Thread.current[:request_id] = id
|
34
|
+
end
|
35
|
+
|
28
36
|
def self.current!
|
29
37
|
current || raise(RequestNotSet)
|
30
38
|
end
|
@@ -45,10 +53,13 @@ module Insights
|
|
45
53
|
|
46
54
|
def self.with_request(request)
|
47
55
|
saved = current
|
56
|
+
saved_request_id = current&.request_id
|
48
57
|
self.current = request
|
58
|
+
self.current_request_id = current&.request_id
|
49
59
|
yield current
|
50
60
|
ensure
|
51
61
|
self.current = saved
|
62
|
+
self.current_request_id = saved_request_id
|
52
63
|
end
|
53
64
|
|
54
65
|
def self.current_forwardable
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: insights-api-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Insights Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_tenant
|
@@ -142,6 +142,20 @@ dependencies:
|
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: 0.10.0
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: insights-rbac-api-client
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '1.0'
|
152
|
+
type: :runtime
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '1.0'
|
145
159
|
- !ruby/object:Gem::Dependency
|
146
160
|
name: graphql
|
147
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -278,16 +292,16 @@ dependencies:
|
|
278
292
|
name: simplecov
|
279
293
|
requirement: !ruby/object:Gem::Requirement
|
280
294
|
requirements:
|
281
|
-
- - "
|
295
|
+
- - "~>"
|
282
296
|
- !ruby/object:Gem::Version
|
283
|
-
version:
|
297
|
+
version: 0.17.1
|
284
298
|
type: :development
|
285
299
|
prerelease: false
|
286
300
|
version_requirements: !ruby/object:Gem::Requirement
|
287
301
|
requirements:
|
288
|
-
- - "
|
302
|
+
- - "~>"
|
289
303
|
- !ruby/object:Gem::Version
|
290
|
-
version:
|
304
|
+
version: 0.17.1
|
291
305
|
- !ruby/object:Gem::Dependency
|
292
306
|
name: webmock
|
293
307
|
requirement: !ruby/object:Gem::Requirement
|
@@ -357,6 +371,7 @@ files:
|
|
357
371
|
- lib/insights/api/common/open_api/docs/object_definition.rb
|
358
372
|
- lib/insights/api/common/open_api/generator.rb
|
359
373
|
- lib/insights/api/common/open_api/serializer.rb
|
374
|
+
- lib/insights/api/common/open_api/version_from_prefix.rb
|
360
375
|
- lib/insights/api/common/option_redirect_enhancements.rb
|
361
376
|
- lib/insights/api/common/paginated_response.rb
|
362
377
|
- lib/insights/api/common/paginated_response_v2.rb
|