44from math import ceil
55from time import mktime
66
7- from mongodb_consistent_backup .Common import DB , MongoUri
7+ from mongodb_consistent_backup .Common import DB , MongoUri , parse_read_pref_tags
88from mongodb_consistent_backup .Errors import Error , OperationError
99
1010
1111class Replset :
1212 def __init__ (self , config , db ):
13- self .config = config
14- self .db = db
15- self .max_lag_secs = self .config .replication .max_lag_secs
16- self .min_priority = self .config .replication .min_priority
17- self .max_priority = self .config .replication .max_priority
18- self .hidden_only = self .config .replication .hidden_only
13+ self .config = config
14+ self .db = db
15+ self .read_pref_tags = self .config .replication .read_pref_tags
16+ self .max_lag_secs = self .config .replication .max_lag_secs
17+ self .min_priority = self .config .replication .min_priority
18+ self .max_priority = self .config .replication .max_priority
19+ self .hidden_only = self .config .replication .hidden_only
1920
2021 self .hidden_weight = 0.20
2122 self .pri0_weight = 0.10
@@ -139,6 +140,18 @@ def is_member_electable(self, member):
139140 return True
140141 return False
141142
143+ def has_read_pref_tags (self , member_config ):
144+ if "tags" not in member_config :
145+ raise OperationError ("Member config has no 'tags' field!" )
146+ tags = parse_read_pref_tags (self .read_pref_tags )
147+ member_tags = member_config ["tags" ]
148+ for key in tags :
149+ if key not in member_tags :
150+ return False
151+ if member_tags [key ] != tags [key ]:
152+ return False
153+ return True
154+
142155 def find_primary (self , force = False , quiet = False ):
143156 if force or not self .primary :
144157 rs_status = self .get_rs_status (force , quiet )
@@ -170,8 +183,8 @@ def find_secondary(self, force=False, quiet=False):
170183 self .get_rs_config (force , quiet )
171184 self .get_mongo_config (force , quiet )
172185
173- quorum = self .get_rs_quorum ()
174- rs_name = rs_status ['set' ]
186+ quorum = self .get_rs_quorum ()
187+ rs_name = rs_status ['set' ]
175188
176189 if self .secondary and not force :
177190 return self .secondary
@@ -193,6 +206,12 @@ def find_secondary(self, force=False, quiet=False):
193206 score = self .max_lag_secs * 10
194207 score_scale = 100 / score
195208 priority = 0
209+
210+ if self .read_pref_tags :
211+ if not self .has_read_pref_tags (member_config ):
212+ logging .info ("Found SECONDARY %s without required read preference tags, skipping" % member_uri )
213+ continue
214+
196215 if 'hidden' in member_config and member_config ['hidden' ]:
197216 score += (score * self .hidden_weight )
198217 log_data ['hidden' ] = True
0 commit comments