yes-core 2.3.0 → 2.4.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a67f053c3f41a210b9efa97b11c975194c9af6578ca5b4ba5f6de062031621c2
|
|
4
|
+
data.tar.gz: 9491e1f3a769af3131ca2b70d5c03746401f78adb6513868abdab14f219334a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae85c83e3178ff406651ef1f42c2fd3a4e54326f6a58290e2aa1ac4fa9dd73cff7d957124d20257809b379b5afb3ea39a441d835c04a43eb940c4fb1557df673
|
|
7
|
+
data.tar.gz: 7bd2ff74f1549b45c76ce29559486222b754652b59bc2d1488e8e528130784521f04f21151f562f96c0b801c8fbf5827c99d75b99515d1a46abae61c4e9ede42
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,10 @@ module Yes
|
|
|
5
5
|
module Authorization
|
|
6
6
|
# Provides a shared Cerbos client instance for authorizer classes.
|
|
7
7
|
#
|
|
8
|
+
# One client (and therefore one gRPC channel) is kept per process. `Cerbos::Client` is
|
|
9
|
+
# thread-safe, but a gRPC channel must not be shared across a fork, so the client is
|
|
10
|
+
# rebuilt in each forked worker.
|
|
11
|
+
#
|
|
8
12
|
# @example Including in a class with class-level methods
|
|
9
13
|
# class MyAuthorizer
|
|
10
14
|
# class << self
|
|
@@ -12,14 +16,47 @@ module Yes
|
|
|
12
16
|
# end
|
|
13
17
|
# end
|
|
14
18
|
module CerbosClientProvider
|
|
19
|
+
class << self
|
|
20
|
+
# @return [Cerbos::Client] the process-wide Cerbos client
|
|
21
|
+
def client
|
|
22
|
+
mutex.synchronize do
|
|
23
|
+
reset! unless @client_pid == Process.pid
|
|
24
|
+
@client ||= build_client
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Drops the memoized client so the next call builds a new one (used after a fork and
|
|
29
|
+
# in tests).
|
|
30
|
+
# @return [void]
|
|
31
|
+
def reset!
|
|
32
|
+
@client = nil
|
|
33
|
+
@client_pid = Process.pid
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# @return [Mutex]
|
|
39
|
+
def mutex
|
|
40
|
+
@mutex ||= Mutex.new
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [Cerbos::Client] client configured from Yes::Core configuration
|
|
44
|
+
def build_client
|
|
45
|
+
config = Yes::Core.configuration
|
|
46
|
+
|
|
47
|
+
Cerbos::Client.new(
|
|
48
|
+
config.cerbos_url,
|
|
49
|
+
tls: config.cerbos_tls,
|
|
50
|
+
grpc_channel_args: config.cerbos_grpc_channel_args
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
15
55
|
private
|
|
16
56
|
|
|
17
|
-
# @return [Cerbos::Client] Cerbos client
|
|
57
|
+
# @return [Cerbos::Client] the process-wide Cerbos client
|
|
18
58
|
def cerbos_client
|
|
19
|
-
|
|
20
|
-
Yes::Core.configuration.cerbos_url,
|
|
21
|
-
tls: Yes::Core.configuration.cerbos_tls
|
|
22
|
-
)
|
|
59
|
+
CerbosClientProvider.client
|
|
23
60
|
end
|
|
24
61
|
end
|
|
25
62
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yes
|
|
4
|
+
module Core
|
|
5
|
+
module Authorization
|
|
6
|
+
# Default gRPC channel arguments for the Cerbos client.
|
|
7
|
+
#
|
|
8
|
+
# A Cerbos PDP pod that is killed or restarting fails an in-flight check with gRPC status
|
|
9
|
+
# `UNAVAILABLE` ("Stream removed", "Connection refused"). gRPC retries such calls
|
|
10
|
+
# transparently when the channel carries a retry policy in its service config, so the
|
|
11
|
+
# caller never sees a `Cerbos::Error::Unavailable` for a blip that a second attempt on a
|
|
12
|
+
# healthy pod would have answered.
|
|
13
|
+
#
|
|
14
|
+
# @see https://grpc.io/docs/guides/retry/
|
|
15
|
+
module CerbosGrpcRetryPolicy
|
|
16
|
+
SERVICE_NAME = 'cerbos.svc.v1.CerbosService'
|
|
17
|
+
MAX_ATTEMPTS = 4
|
|
18
|
+
INITIAL_BACKOFF = '0.1s'
|
|
19
|
+
MAX_BACKOFF = '1s'
|
|
20
|
+
BACKOFF_MULTIPLIER = 2
|
|
21
|
+
RETRYABLE_STATUS_CODES = %w[UNAVAILABLE].freeze
|
|
22
|
+
|
|
23
|
+
ENABLE_RETRIES_ARG = 'grpc.enable_retries'
|
|
24
|
+
SERVICE_CONFIG_ARG = 'grpc.service_config'
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# @return [Hash{String => Integer, String}] channel arguments for `Cerbos::Client.new`
|
|
28
|
+
def channel_args
|
|
29
|
+
{
|
|
30
|
+
ENABLE_RETRIES_ARG => 1,
|
|
31
|
+
SERVICE_CONFIG_ARG => service_config.to_json
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [Hash] gRPC service config with the retry policy for the Cerbos service
|
|
36
|
+
def service_config
|
|
37
|
+
{
|
|
38
|
+
methodConfig: [
|
|
39
|
+
{
|
|
40
|
+
name: [{ service: SERVICE_NAME }],
|
|
41
|
+
retryPolicy: {
|
|
42
|
+
maxAttempts: MAX_ATTEMPTS,
|
|
43
|
+
initialBackoff: INITIAL_BACKOFF,
|
|
44
|
+
maxBackoff: MAX_BACKOFF,
|
|
45
|
+
backoffMultiplier: BACKOFF_MULTIPLIER,
|
|
46
|
+
retryableStatusCodes: RETRYABLE_STATUS_CODES
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -45,6 +45,10 @@ module Yes
|
|
|
45
45
|
# @return [Boolean] Whether to use TLS for Cerbos connections (default: true)
|
|
46
46
|
attr_accessor :cerbos_tls
|
|
47
47
|
|
|
48
|
+
# @return [Hash{String => String, Integer}] low-level gRPC channel arguments for the Cerbos client
|
|
49
|
+
# (default: {Authorization::CerbosGrpcRetryPolicy.channel_args}, which retries UNAVAILABLE calls)
|
|
50
|
+
attr_accessor :cerbos_grpc_channel_args
|
|
51
|
+
|
|
48
52
|
# @return [Boolean] Whether to include metadata in Cerbos command authorizer responses
|
|
49
53
|
attr_accessor :cerbos_commands_authorizer_include_metadata
|
|
50
54
|
|
|
@@ -112,6 +116,7 @@ module Yes
|
|
|
112
116
|
}
|
|
113
117
|
@cerbos_url = ENV.fetch('CERBOS_URL', 'cerbos-cluster-ip-service:3593')
|
|
114
118
|
@cerbos_tls = true
|
|
119
|
+
@cerbos_grpc_channel_args = Authorization::CerbosGrpcRetryPolicy.channel_args
|
|
115
120
|
@cerbos_commands_authorizer_include_metadata = false
|
|
116
121
|
@cerbos_read_authorizer_include_metadata = false
|
|
117
122
|
@cerbos_read_authorizer_actions = %w[read]
|
data/lib/yes/core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yes-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nico Ritsche
|
|
@@ -222,6 +222,7 @@ files:
|
|
|
222
222
|
- lib/yes/core/aggregate/shared_read_model_rebuilder.rb
|
|
223
223
|
- lib/yes/core/authentication_error.rb
|
|
224
224
|
- lib/yes/core/authorization/cerbos_client_provider.rb
|
|
225
|
+
- lib/yes/core/authorization/cerbos_grpc_retry_policy.rb
|
|
225
226
|
- lib/yes/core/authorization/command_authorizer.rb
|
|
226
227
|
- lib/yes/core/authorization/command_cerbos_authorizer.rb
|
|
227
228
|
- lib/yes/core/authorization/lookup_cache.rb
|