5
5
import hashlib
6
6
import time
7
7
import functools
8
- from typing import Dict , List
9
8
from urllib .parse import urlsplit
10
9
11
10
from django .conf import settings
@@ -187,50 +186,36 @@ def __init__(self, varnish, input_data):
187
186
'mesh_routing' : varnish .cluster .service_mesh_routing
188
187
}
189
188
190
- def filter_cluster_domain_mappings (
191
- self , cluster : LogicalCluster
192
- ) -> dict [str , list [str ]]:
193
- """Returns a dictionary where keys are domains, and values are mapped to by the key"""
194
- # we can PROBABLY assume that each domain has only one mapping
195
- # in an experiment trying to add a new mapping for a source domain removed the old one
196
- destination_dict = {}
197
- for domain_mapping in self .input .domain_mappings :
198
- domain = domain_mapping .domain
199
- destination_dict [domain ] = domain_mapping .mapped_domains (cluster )
200
- return destination_dict
201
-
202
- def provide_related_domains (self , cluster : LogicalCluster ) -> list [str ]:
203
- """Returns a list of all domains related to a cluster - for static mappings,
204
- the list is specified within the mapping, for dynamic - clusters are associated using
205
- labels (mapping targets can contain labels, and each cluster can have multiple labels, but
206
- each label belongs to exactly one cluster)"""
207
- result = {m .domain for m in self .input .static_domain_mappings_by_cluster [cluster .name ]}
208
- for m in self .input .mapping_provider .mappings ["dynamic" ]:
209
- if m .is_cluster_related_by_labels (cluster ):
210
- result .add (m .domain )
211
- return sorted (list (result ))
189
+ def fetch_all_destinations_mappings (self , cluster : LogicalCluster , redirect : str ,
190
+ domain_mappings : list [DomainMapping ]) -> tuple [str , list [str ]]:
191
+ """Fetch tuple containing domain parsed from destination url and all found mappings for input cluster
192
+ """
193
+ all_mappings = set ()
194
+ destination_domain = urlsplit (redirect ).netloc
195
+ for domain_mapping in domain_mappings :
196
+ all_mappings = all_mappings .union (set (domain_mapping .mapped_domains (cluster )))
197
+ return destination_domain , list (all_mappings )
212
198
213
199
@collect_processing
214
- def prepare_redirects (self ) -> Dict [str , List [VclRedirect ]]:
215
- redirects = {}
216
- related_domains = self .provide_related_domains (self .varnish .cluster )
217
- destinations_dict = self .filter_cluster_domain_mappings (self .varnish .cluster )
218
- for redirect in self .input .redirects :
219
- if str (redirect .src_domain ) not in related_domains :
200
+ def prepare_redirects (self ) -> dict [str , list [VclRedirect ]]:
201
+ redirects = dict ()
202
+ related_domains = self .input .mapping_provider .provide_related_domains (self .varnish .cluster )
203
+ for related_domain in related_domains :
204
+ if related_domain not in self .input .redirects .keys ():
220
205
continue
221
- destination_domain = urlsplit ( redirect . destination ). netloc
222
- destination_mappings = destinations_dict . get ( destination_domain )
223
- for mapped_domain in redirect . src_domain . mapped_domains ( self .varnish .cluster ):
224
- destination = str ( redirect .destination )
225
- if destination_domain == redirect .src_domain . domain :
226
- destination = destination . replace ( destination_domain , mapped_domain )
227
- elif destination_domain and len ( destination_mappings ) == 1 :
228
- destination = destination . replace ( destination_domain , destination_mappings [ 0 ])
229
-
230
- if entries := redirects .get (mapped_domain , []):
231
- entries .append (VclRedirect (redirect , mapped_domain , destination ))
232
- else :
233
- redirects [mapped_domain ] = [VclRedirect (redirect , mapped_domain , destination )]
206
+ for redirect in self . input . redirects . get ( related_domain ):
207
+ destination_domain , destination_mappings = self . fetch_all_destinations_mappings (
208
+ self .varnish .cluster , redirect . destination , self . input . domain_mappings )
209
+ for mapped_domain in redirect .src_domain . mapped_domains ( self . varnish . cluster ):
210
+ destination = str ( redirect .destination )
211
+ if destination_domain == redirect . src_domain . domain :
212
+ destination = destination . replace ( destination_domain , mapped_domain )
213
+ elif all (( destination_domain , len ( destination_mappings ) == 1 )):
214
+ destination = destination . replace ( destination_domain , destination_mappings [ 0 ])
215
+ if entries := redirects .get (mapped_domain , []):
216
+ entries .append (VclRedirect (redirect , mapped_domain , destination ))
217
+ else :
218
+ redirects [mapped_domain ] = [VclRedirect (redirect , mapped_domain , destination )]
234
219
return redirects
235
220
236
221
@collect_processing
@@ -410,7 +395,7 @@ def fetch_render_data(self):
410
395
Prefetch ('clusters' , queryset = LogicalCluster .objects .only ('pk' ), to_attr = 'cluster_ids' ),
411
396
))
412
397
self .routes .sort (key = lambda route : "{:03d}-{}" .format (route .priority , route .director .name ))
413
- self .redirects = list ( Redirect . objects . all (). order_by ( 'src_domain' , 'priority' ) )
398
+ self .redirects = self . assemble_redirects ( )
414
399
self .dcs = list (Dc .objects .all ())
415
400
self .template_blocks = list (VclTemplateBlock .objects .all ().prefetch_related ('template' ))
416
401
self .vcl_variables = list (VclVariable .objects .all ())
@@ -422,16 +407,15 @@ def fetch_render_data(self):
422
407
self .distributed_canary_backends = self .prepare_canary_backends (canary_backend_ids , backends )
423
408
self .domain_mappings = DomainMapping .objects .all ()
424
409
self .mapping_provider = MappingProvider (self .domain_mappings )
425
- self .static_domain_mappings_by_cluster = self .cluster_static_domain_mappings ()
426
-
427
- def cluster_static_domain_mappings (self ) -> dict [str , list [DomainMapping ]]:
428
- """Returns a dict cluster.name: [associated domain mappings]"""
429
- # NTH: get the same output with only one database query, perhaps with prefetch_related()
430
- result_dict = dict ()
431
- all_clusters = LogicalCluster .objects .all ()
432
- for cluster in all_clusters :
433
- result_dict [cluster .name ] = cluster .domainmapping_set .filter (type = "static" )
434
- return result_dict
410
+
411
+ @collect_processing
412
+ def assemble_redirects (self ) -> dict [str , list [Redirect ]]:
413
+ redirects = {}
414
+ for redirect in Redirect .objects .all ().order_by ('src_domain' , 'priority' ):
415
+ if redirect .src_domain .domain not in redirects .keys ():
416
+ redirects [redirect .src_domain .domain ] = []
417
+ redirects [redirect .src_domain .domain ].append (redirect )
418
+ return redirects
435
419
436
420
@collect_processing
437
421
def distribute_backends (self , backends ):
0 commit comments