@@ -160,6 +160,42 @@ def send(self) -> None:
160160 """Send instruction to the proxy at /mocked_tracer_responses endpoint."""
161161 self ._send_to_endpoint (MOCKED_TRACER_RESPONSES_PATH )
162162
163+ @staticmethod
164+ def _gate_rc_response_by_products (response : dict , request_content : dict ) -> dict :
165+ """Restrict a /v0.7/config response to the products the client subscribed to.
166+
167+ The real Datadog agent only returns configs for products listed in the
168+ request's ``client.products``. Mirror the real-world behaviour here.
169+ """
170+ if not isinstance (response , dict ):
171+ return response
172+ client_configs = response .get ("client_configs" )
173+ if not isinstance (client_configs , list ):
174+ return response
175+ try :
176+ products = request_content ["client" ]["products" ]
177+ except (KeyError , TypeError ):
178+ return response
179+ if not isinstance (products , list ):
180+ return response
181+ allowed = set (products )
182+
183+ def product_of (path : str ) -> str | None :
184+ # datadog/<org_id>/<PRODUCT>/<config_id>/<name> or employee/<PRODUCT>/<config_id>/<name>
185+ parts = path .split ("/" )
186+ return parts [- 3 ]
187+
188+ kept = [path for path in client_configs if product_of (path ) in allowed ]
189+ if kept == client_configs :
190+ return response
191+ filtered = dict (response )
192+ filtered ["client_configs" ] = kept
193+ target_files = response .get ("target_files" )
194+ if isinstance (target_files , list ):
195+ kept_paths = set (kept )
196+ filtered ["target_files" ] = [tf for tf in target_files if tf .get ("path" ) in kept_paths ]
197+ return filtered
198+
163199
164200class StaticJsonMockedTracerResponse (MockedTracerResponse ):
165201 """Always overwrites the same static JSON content on request made on the given path."""
@@ -175,7 +211,15 @@ def _apply_status_code(self, flow: HTTPFlow) -> None:
175211
176212 def execute (self , flow : HTTPFlow ) -> None :
177213 super ().execute (flow )
178- flow .response .content = json .dumps (self .mocked_json ).encode ()
214+ response = self .mocked_json
215+ if self .path == "/v0.7/config" and isinstance (response , dict ):
216+ try :
217+ request_content = json .loads (flow .request .content )
218+ except (ValueError , TypeError ):
219+ request_content = None
220+ if isinstance (request_content , dict ):
221+ response = self ._gate_rc_response_by_products (response , request_content )
222+ flow .response .content = json .dumps (response ).encode ()
179223
180224 def to_json (self ) -> dict :
181225 return {
@@ -203,7 +247,7 @@ def execute(self, flow: HTTPFlow) -> None:
203247 request_content = json .loads (flow .request .content )
204248 runtime_id = request_content ["client" ]["client_tracer" ]["runtime_id" ]
205249 nth_api_command = self ._runtime_ids_request_count [runtime_id ]
206- response = self .mocked_json_sequence [nth_api_command ]
250+ response = self ._gate_rc_response_by_products ( self . mocked_json_sequence [nth_api_command ], request_content )
207251
208252 flow .response .content = json .dumps (response ).encode ()
209253 flow .response .headers ["st-proxy-overwrite-rc-response" ] = f"{ nth_api_command } "
0 commit comments