Skip to content

Commit 0257fc7

Browse files
committed
feat(flagd): Add features to customize auth to Sync API servers
Signed-off-by: Maks Osowski <[email protected]>
1 parent b226728 commit 0257fc7

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/config.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dataclasses
2+
import grpc
23
import os
34
import typing
45
from enum import Enum
@@ -45,9 +46,11 @@ class CacheType(Enum):
4546
ENV_VAR_RETRY_BACKOFF_MAX_MS = "FLAGD_RETRY_BACKOFF_MAX_MS"
4647
ENV_VAR_RETRY_GRACE_PERIOD_SECONDS = "FLAGD_RETRY_GRACE_PERIOD"
4748
ENV_VAR_SELECTOR = "FLAGD_SOURCE_SELECTOR"
49+
ENV_VAR_PROVIDER_ID = "FLAGD_SOURCE_PROVIDER_ID"
4850
ENV_VAR_STREAM_DEADLINE_MS = "FLAGD_STREAM_DEADLINE_MS"
4951
ENV_VAR_TLS = "FLAGD_TLS"
5052
ENV_VAR_TLS_CERT = "FLAGD_SERVER_CERT_PATH"
53+
ENV_VAR_DEFAULT_AUTHORITY = "FLAGD_DEFAULT_AUTHORITY"
5154

5255
T = typing.TypeVar("T")
5356

@@ -81,6 +84,7 @@ def __init__( # noqa: PLR0913
8184
port: typing.Optional[int] = None,
8285
tls: typing.Optional[bool] = None,
8386
selector: typing.Optional[str] = None,
87+
provider_id: typing.Optional[str] = None,
8488
resolver: typing.Optional[ResolverType] = None,
8589
offline_flag_source_path: typing.Optional[str] = None,
8690
offline_poll_interval_ms: typing.Optional[int] = None,
@@ -93,6 +97,8 @@ def __init__( # noqa: PLR0913
9397
cache: typing.Optional[CacheType] = None,
9498
max_cache_size: typing.Optional[int] = None,
9599
cert_path: typing.Optional[str] = None,
100+
default_authority: typing.Optional[str] = None,
101+
channel_credentials: typing.Optional[grpc.ChannelCredentials] = None,
96102
):
97103
self.host = env_or_default(ENV_VAR_HOST, DEFAULT_HOST) if host is None else host
98104

@@ -227,3 +233,13 @@ def __init__( # noqa: PLR0913
227233
self.selector = (
228234
env_or_default(ENV_VAR_SELECTOR, None) if selector is None else selector
229235
)
236+
237+
self.provider_id = (
238+
env_or_default(ENV_VAR_PROVIDER_ID, None) if provider_id is None else provider_id
239+
)
240+
241+
self.default_authority = (
242+
env_or_default(ENV_VAR_DEFAULT_AUTHORITY, None) if default_authority is None else default_authority
243+
)
244+
245+
self.channel_credentials = channel_credentials

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/provider.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# provider.initialise(schema="https",endpoint="example.com",port=1234,timeout=10)
2222
"""
2323

24+
import grpc
2425
import typing
2526
import warnings
2627

@@ -47,6 +48,7 @@ def __init__( # noqa: PLR0913
4748
timeout: typing.Optional[int] = None,
4849
retry_backoff_ms: typing.Optional[int] = None,
4950
selector: typing.Optional[str] = None,
51+
provider_id: typing.Optional[str] = None,
5052
resolver_type: typing.Optional[ResolverType] = None,
5153
offline_flag_source_path: typing.Optional[str] = None,
5254
stream_deadline_ms: typing.Optional[int] = None,
@@ -56,6 +58,8 @@ def __init__( # noqa: PLR0913
5658
retry_backoff_max_ms: typing.Optional[int] = None,
5759
retry_grace_period: typing.Optional[int] = None,
5860
cert_path: typing.Optional[str] = None,
61+
default_authority: typing.Optional[str] = None,
62+
grpc_credentials: typing.Optional[grpc.ChannelCredentials] = None,
5963
):
6064
"""
6165
Create an instance of the FlagdProvider
@@ -88,13 +92,16 @@ def __init__( # noqa: PLR0913
8892
retry_backoff_max_ms=retry_backoff_max_ms,
8993
retry_grace_period=retry_grace_period,
9094
selector=selector,
95+
provider_id=provider_id,
9196
resolver=resolver_type,
9297
offline_flag_source_path=offline_flag_source_path,
9398
stream_deadline_ms=stream_deadline_ms,
9499
keep_alive_time=keep_alive_time,
95100
cache=cache,
96101
max_cache_size=max_cache_size,
97102
cert_path=cert_path,
103+
default_authority=default_authority,
104+
channel_credentials=grpc_credentials,
98105
)
99106

100107
self.resolver = self.setup_resolver()

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def __init__(
4141
self.streamline_deadline_seconds = config.stream_deadline_ms * 0.001
4242
self.deadline = config.deadline_ms * 0.001
4343
self.selector = config.selector
44+
self.provider_id = config.provider_id
4445
self.emit_provider_ready = emit_provider_ready
4546
self.emit_provider_error = emit_provider_error
4647
self.emit_provider_stale = emit_provider_stale
@@ -60,7 +61,17 @@ def _generate_channel(self, config: Config) -> grpc.Channel:
6061
("grpc.max_reconnect_backoff_ms", config.retry_backoff_max_ms),
6162
("grpc.min_reconnect_backoff_ms", config.stream_deadline_ms),
6263
]
63-
if config.tls:
64+
if config.default_authority is not None:
65+
options.append(("grpc.default_authority", config.default_authority))
66+
67+
if config.channel_credentials is not None:
68+
channel_args = {
69+
"options": options,
70+
"credentials": config.channel_credentials,
71+
}
72+
channel = grpc.secure_channel(target, **channel_args)
73+
74+
elif config.tls:
6475
channel_args = {
6576
"options": options,
6677
"credentials": grpc.ssl_channel_credentials(),
@@ -153,7 +164,11 @@ def listen(self) -> None:
153164
if self.streamline_deadline_seconds > 0
154165
else {}
155166
)
156-
request_args = {"selector": self.selector} if self.selector is not None else {}
167+
request_args = {}
168+
if self.selector is not None:
169+
request_args["selector"] = self.selector
170+
if self.provider_id is not None:
171+
request_args["provider_id"] = self.provider_id
157172

158173
while self.active:
159174
try:

0 commit comments

Comments
 (0)