From e7dd9bf341db89523e526795d8561d3c3dd2b385 Mon Sep 17 00:00:00 2001 From: Github Actions Date: Wed, 17 Apr 2024 12:01:57 +0000 Subject: [PATCH] chore: update charm libraries --- lib/charms/tempo_k8s/v1/tracing.py | 54 +++++++++++++++++++----------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/charms/tempo_k8s/v1/tracing.py b/lib/charms/tempo_k8s/v1/tracing.py index 3ffcc044..30566adc 100644 --- a/lib/charms/tempo_k8s/v1/tracing.py +++ b/lib/charms/tempo_k8s/v1/tracing.py @@ -93,7 +93,7 @@ def __init__(self, *args): # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 3 +LIBPATCH = 4 PYDEPS = ["pydantic>=2"] @@ -106,7 +106,7 @@ def __init__(self, *args): "otlp_grpc", "otlp_http", "zipkin", "tempo", "jaeger_http_thrift", "jaeger_grpc" ] -RawIngester = Tuple[IngesterProtocol, int] +RawIngester = Tuple[IngesterProtocol, int, str] BUILTIN_JUJU_KEYS = {"ingress-address", "private-address", "egress-subnets"} @@ -126,6 +126,8 @@ class DatabagModel(BaseModel): """Base databag model.""" model_config = ConfigDict( + # ignore extra fields in config + extra="ignore", # Allow instantiating this class by field name (instead of forcing alias). populate_by_name=True, # Custom config key: whether to nest the whole datastructure (as json) @@ -172,7 +174,7 @@ def dump(self, databag: Optional[MutableMapping] = None, clear: bool = True): databag = {} nest_under = self.model_config.get("_NEST_UNDER") if nest_under: - databag[nest_under] = self.json() + databag[nest_under] = self.json(exclude_none=True) dct = self.model_dump() for key, field in self.model_fields.items(): # type: ignore @@ -188,6 +190,7 @@ class Ingester(BaseModel): # noqa: D101 protocol: IngesterProtocol port: int + path: Optional[str] = None class TracingProviderAppData(DatabagModel): # noqa: D101 @@ -394,8 +397,8 @@ def _on_relation_event(self, _): TracingProviderAppData( host=self._host, ingesters=[ - Ingester(port=port, protocol=protocol) - for protocol, port in self._ingesters + Ingester(port=port, protocol=protocol, path=path) + for protocol, port, path in self._ingesters ], ).dump(relation.data[self._charm.app]) @@ -547,28 +550,39 @@ def get_all_endpoints( self, relation: Optional[Relation] = None ) -> Optional[TracingProviderAppData]: """Unmarshalled relation data.""" - if not self.is_ready(relation or self._relation): + relation = relation or self._relation + if not self.is_ready(relation): return return TracingProviderAppData.load(relation.data[relation.app]) # type: ignore def _get_ingester( self, relation: Optional[Relation], protocol: IngesterProtocol, ssl: bool = False ): - ep = self.get_all_endpoints(relation) - if not ep: - return None - try: - ingester: Ingester = next(filter(lambda i: i.protocol == protocol, ep.ingesters)) - if ingester.protocol in ["otlp_grpc", "jaeger_grpc"]: - if ssl: - logger.warning("unused ssl argument - was the right protocol called?") - return f"{ep.host}:{ingester.port}" - if ssl: - return f"https://{ep.host}:{ingester.port}" - return f"http://{ep.host}:{ingester.port}" - except StopIteration: - logger.error(f"no ingester found with protocol={protocol!r}") + app_data = self.get_all_endpoints(relation) + if not app_data: return None + receivers: List[Ingester] = list( + filter(lambda i: i.protocol == protocol, app_data.ingesters) + ) + if not receivers: + logger.error(f"no receiver found with protocol={protocol!r}") + return + if len(receivers) > 1: + logger.error( + f"too many receivers with protocol={protocol!r}; using first one. Found: {receivers}" + ) + return + + receiver = receivers[0] + # FIXME: when to use https? ASSUME HTTP + base_url = f"http://{app_data.host}:{receiver.port}" + + if receiver.protocol.endswith("grpc"): + # TCP protocols don't want an http/https scheme prefix + base_url = base_url.split("://")[1] + + suffix = receiver.path or "" + return f"{base_url}{suffix}" def otlp_grpc_endpoint(self, relation: Optional[Relation] = None) -> Optional[str]: """Ingester endpoint for the ``otlp_grpc`` protocol."""