|
15 | 15 |
|
16 | 16 | import argparse
|
17 | 17 | import logging
|
18 |
| -from typing import Any, Dict, List, Union |
| 18 | +from typing import Any, Dict, List, Optional, Union |
19 | 19 |
|
20 | 20 | import attr
|
21 | 21 | from pydantic import BaseModel, Extra, StrictBool, StrictInt, StrictStr
|
@@ -171,6 +171,27 @@ class WriterLocations:
|
171 | 171 | )
|
172 | 172 |
|
173 | 173 |
|
| 174 | +@attr.s(auto_attribs=True) |
| 175 | +class OutboundFederationRestrictedTo: |
| 176 | + """Whether we limit outbound federation to a certain set of instances. |
| 177 | +
|
| 178 | + Attributes: |
| 179 | + instances: optional list of instances that can make outbound federation |
| 180 | + requests. If None then all instances can make federation requests. |
| 181 | + locations: list of instance locations to connect to proxy via. |
| 182 | + """ |
| 183 | + |
| 184 | + instances: Optional[List[str]] |
| 185 | + locations: List[InstanceLocationConfig] = attr.Factory(list) |
| 186 | + |
| 187 | + def __contains__(self, instance: str) -> bool: |
| 188 | + # It feels a bit dirty to return `True` if `instances` is `None`, but it makes |
| 189 | + # sense in downstream usage in the sense that if |
| 190 | + # `outbound_federation_restricted_to` is not configured, then any instance can |
| 191 | + # talk to federation (no restrictions so always return `True`). |
| 192 | + return self.instances is None or instance in self.instances |
| 193 | + |
| 194 | + |
174 | 195 | class WorkerConfig(Config):
|
175 | 196 | """The workers are processes run separately to the main synapse process.
|
176 | 197 | They have their own pid_file and listener configuration. They use the
|
@@ -385,6 +406,28 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
|
385 | 406 | new_option_name="update_user_directory_from_worker",
|
386 | 407 | )
|
387 | 408 |
|
| 409 | + outbound_federation_restricted_to = config.get( |
| 410 | + "outbound_federation_restricted_to", None |
| 411 | + ) |
| 412 | + self.outbound_federation_restricted_to = OutboundFederationRestrictedTo( |
| 413 | + outbound_federation_restricted_to |
| 414 | + ) |
| 415 | + if outbound_federation_restricted_to: |
| 416 | + if not self.worker_replication_secret: |
| 417 | + raise ConfigError( |
| 418 | + "`worker_replication_secret` must be configured when using `outbound_federation_restricted_to`." |
| 419 | + ) |
| 420 | + |
| 421 | + for instance in outbound_federation_restricted_to: |
| 422 | + if instance not in self.instance_map: |
| 423 | + raise ConfigError( |
| 424 | + "Instance %r is configured in 'outbound_federation_restricted_to' but does not appear in `instance_map` config." |
| 425 | + % (instance,) |
| 426 | + ) |
| 427 | + self.outbound_federation_restricted_to.locations.append( |
| 428 | + self.instance_map[instance] |
| 429 | + ) |
| 430 | + |
388 | 431 | def _should_this_worker_perform_duty(
|
389 | 432 | self,
|
390 | 433 | config: Dict[str, Any],
|
|
0 commit comments